package migration

import (
	"errors"
	"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 32c64g n2 tidb instance type and sku
var _ = AddDBMigrateRecord(
	"202509081200",
	func(db *gorm.DB) error {
		timestamp := time.Now()

		return db.Transaction(func(tx *gorm.DB) error {
			// Fetch the GCP provider.
			var provider *schema.Provider
			if err := tx.Where("name = ?", "gcp").First(&provider).Error; err != nil {
				return err
			}

			if provider == nil || provider.ID == 0 {
				return errors.New("invalid GCP provider data")
			}

			// Add instance types.
			instanceTypes := []*schema.InstanceType{
				{
					InstanceType: "n2-custom-32-65536",
					ProviderId:   uint64(provider.ID),
					CPUNum:       32,
					MemorySizeGi: 64,
					CpuArch:      "amd64",
				},
			}
			for _, instanceType := range instanceTypes {
				instanceType.CreatedAt = timestamp
				instanceType.UpdatedAt = timestamp
				if err := tx.Clauses(clause.OnConflict{
					Columns:   []clause.Column{{Name: "instance_type"}},
					UpdateAll: true,
				}).Create(instanceType).Error; err != nil {
					return err
				}
			}

			// Verify all instance types were created and have valid IDs
			for _, instanceType := range instanceTypes {
				if instanceType.ID == 0 {
					return fmt.Errorf("instance type %s was not assigned a valid ID", instanceType.InstanceType)
				}
			}

			instanceTypeMap := lo.SliceToMap(
				instanceTypes,
				func(i *schema.InstanceType) (string, *schema.InstanceType) {
					return i.InstanceType, i
				},
			)

			// Add tidb skus.
			{
				tidbSkus := make([]*schema.ComponentTierUnit, 0, 4)

				tidbSpu32c64g := &schema.ComponentTier{
					Key:           "32C64G:DEPLOY_TYPE_DEDICATED:COMPONENT_TYPE_TIDB",
					Name:          "32C64G",
					ComponentType: "tidb",
					DisplayName:   "32 vCPU, 64 GiB",
					CPUNum:        32,
					MemorySizeGi:  64,
					Version:       "V1",
				}
				tidbSpu32c64g.CreatedAt = timestamp
				tidbSpu32c64g.UpdatedAt = timestamp
				if err := tx.Clauses(clause.OnConflict{
					Columns:   []clause.Column{{Name: "key"}},
					UpdateAll: true,
				}).Create(tidbSpu32c64g).Error; err != nil {
					return err
				}
				tidbSkus = append(tidbSkus, &schema.ComponentTierUnit{
					Key:             "gcp:tidb:n2-custom-32-65536",
					Priority:        int32(999),
					ComponentType:   "tidb",
					ProviderId:      uint64(provider.ID),
					ComponentTierId: uint64(tidbSpu32c64g.ID),
					InstanceTypeId:  uint64(instanceTypeMap["n2-custom-32-65536"].ID),
					DefaultNodeNum:  2,
				})

				for _, tidbSku := range tidbSkus {
					tidbSku.CreatedAt = timestamp
					tidbSku.UpdatedAt = timestamp
					if err := tx.Clauses(clause.OnConflict{
						Columns:   []clause.Column{{Name: "key"}},
						UpdateAll: true,
					}).Create(tidbSku).Error; err != nil {
						return err
					}
				}
			}

			return nil
		})
	},
)
