package migration

import (
	"fmt"
	"time"

	"github.com/samber/lo"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"

	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/infra/repoimpl/schema"
)

// Add new Azure TiFlash 16C64G SPU and SKU:
//   - SPU: 16C64G:DEPLOY_TYPE_DEDICATED:COMPONENT_TYPE_TIFLASH
//   - SKU: azure:tiflash:Standard_D16as_v5:premiumv2:16000:1000 (disk config from azure:tiflash:Standard_E16as_v5:premiumv2:16000:594)
var _ = AddDBMigrateRecord(
	"release_20260312_azure_tiflash",
	func(db *gorm.DB) error {
		timestamp := time.Now()

		// Fetch the Azure provider.
		var provider schema.Provider
		if err := db.Where("name = ?", "azure").First(&provider).Error; err != nil {
			return fmt.Errorf("failed to get azure provider: %w", err)
		}

		// Fetch the existing instance type Standard_D16as_v5 (already in metaDB).
		var instanceType schema.InstanceType
		if err := db.Where("instance_type = ?", "Standard_D16as_v5").First(&instanceType).Error; err != nil {
			return fmt.Errorf("failed to get instance type Standard_D16as_v5: %w", err)
		}

		// Fetch the premiumv2 storage template for Azure.
		var storageTemplate schema.StorageTemplate
		if err := db.Where("provider_id = ? AND volume_type = ?", provider.ID, "premiumv2").First(&storageTemplate).Error; err != nil {
			return fmt.Errorf("failed to get premiumv2 storage template for azure: %w", err)
		}

		// Create the new SPU 16C64G:DEPLOY_TYPE_DEDICATED:COMPONENT_TYPE_TIFLASH.
		spu := &schema.ComponentTier{
			Key:           "16C64G:DEPLOY_TYPE_DEDICATED:COMPONENT_TYPE_TIFLASH",
			Name:          "16C64G",
			ComponentType: "tiflash",
			DisplayName:   "16 vCPU, 64 GiB",
			CPUNum:        16,
			MemorySizeGi:  64,
			Version:       "V1",
		}
		spu.CreatedAt = timestamp
		spu.UpdatedAt = timestamp
		if err := db.Clauses(clause.OnConflict{
			Columns:   []clause.Column{{Name: "key"}},
			UpdateAll: true,
		}).Create(spu).Error; err != nil {
			return fmt.Errorf("failed to create SPU %s: %w", spu.Key, err)
		}

		// Re-query SPU to get its ID.
		if err := db.Where("`key` = ?", spu.Key).First(spu).Error; err != nil {
			return fmt.Errorf("failed to re-query SPU %s: %w", spu.Key, err)
		}

		// Create the new SKU azure:tiflash:Standard_D16as_v5:premiumv2:16000:1000.
		// Disk configuration refers to azure:tiflash:Standard_E16as_v5:premiumv2:16000:594.
		sku := &schema.ComponentTierUnit{
			Key:                    "azure:tiflash:Standard_D16as_v5:premiumv2:16000:1000",
			Priority:               999,
			ComponentType:          "tiflash",
			ProviderId:             uint64(provider.ID),
			ComponentTierId:        uint64(spu.ID),
			InstanceTypeId:         uint64(instanceType.ID),
			StorageTemplateId:      lo.ToPtr(uint64(storageTemplate.ID)),
			DefaultNodeNum:         2,
			MinStorageGi:           200,
			MaxStorageGi:           4096,
			DefaultStorageGi:       200,
			DefaultIops:            0,
			DefaultThroughPut:      lo.ToPtr(uint32(0)),
			MaxIops:                16000,
			MinIops:                3000,
			IopsPerGi:              4,
			MaxThroughPut:          1000,
			MinThroughPut:          125,
			ThroughputMibpsPerGi:   0.5,
			ThroughputMibpsPerIops: 0.046875,
		}
		sku.CreatedAt = timestamp
		sku.UpdatedAt = timestamp
		if err := db.Clauses(clause.OnConflict{
			Columns:   []clause.Column{{Name: "key"}},
			UpdateAll: true,
		}).Create(sku).Error; err != nil {
			return fmt.Errorf("failed to create SKU %s: %w", sku.Key, err)
		}

		return nil
	},
)
