package vo

import (
	"bytes"
	"fmt"
	"text/template"

	panicIf "github.com/tidbcloud/pkgv2/panicif" //nolint:revive
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
)

var (
	rowStorageSkuNameTemplate          *template.Template
	columnStorageSkuNameTemplate       *template.Template
	requestUnitSkuNameTemplate         *template.Template
	requestCapacityUnitSkuNameTemplate *template.Template

	// Instance Capacity SKU templates — uniform across providers/regions
	instanceCapacityFreeSkuNameTemplate  *template.Template
	instanceCapacityTier1SkuNameTemplate *template.Template
	instanceCapacityTier2SkuNameTemplate *template.Template
	instanceCapacityTier3SkuNameTemplate *template.Template
	instanceCapacityTier4SkuNameTemplate *template.Template
)

func init() {
	var err error
	rowStorageSkuNameTemplate, err = template.New("sku-row-storage").
		Parse("serverless-row-storage:{{.CloudProvider}}:{{.Region}}:starter")
	panicIf.Error(err)
	columnStorageSkuNameTemplate, err = template.New("sku-column-storage").
		Parse("serverless-column-storage:{{.CloudProvider}}:{{.Region}}:starter")
	panicIf.Error(err)
	requestUnitSkuNameTemplate, err = template.New("sku-request-unit").
		Parse("serverless-request-unit:{{.CloudProvider}}:{{.Region}}:starter")
	panicIf.Error(err)
	requestCapacityUnitSkuNameTemplate, err = template.New("sku-request-capacity-unit").
		Parse("serverless-request-capacity-unit:{{.CloudProvider}}:{{.Region}}:essential")
	panicIf.Error(err)

	// Instance Capacity SKUs — uniform pricing, no provider/region
	instanceCapacityFreeSkuNameTemplate, err = template.New("sku-instance-capacity-free").
		Parse("instance-capacity:free")
	panicIf.Error(err)
	instanceCapacityTier1SkuNameTemplate, err = template.New("sku-instance-capacity-tier1").
		Parse("instance-capacity:tier1")
	panicIf.Error(err)
	instanceCapacityTier2SkuNameTemplate, err = template.New("sku-instance-capacity-tier2").
		Parse("instance-capacity:tier2")
	panicIf.Error(err)
	instanceCapacityTier3SkuNameTemplate, err = template.New("sku-instance-capacity-tier3").
		Parse("instance-capacity:tier3")
	panicIf.Error(err)
	instanceCapacityTier4SkuNameTemplate, err = template.New("sku-instance-capacity-tier4").
		Parse("instance-capacity:tier4")
	panicIf.Error(err)
}

type SkuNameBuilder struct {
	CloudProvider string
	Region        string
}

func (b *SkuNameBuilder) Build(skuType constant.SkuType) string {
	var (
		nameBuffer = bytes.NewBuffer(nil)
		err        error
	)
	switch skuType {
	case constant.SkuTypeRowStorage:
		err = rowStorageSkuNameTemplate.Execute(nameBuffer, b)
	case constant.SkuTypeColumnStorage:
		err = columnStorageSkuNameTemplate.Execute(nameBuffer, b)
	case constant.SkuTypeRequestUnit:
		err = requestUnitSkuNameTemplate.Execute(nameBuffer, b)
	case constant.SkuTypeRequestCapacityUnit:
		err = requestCapacityUnitSkuNameTemplate.Execute(nameBuffer, b)
	case constant.SkuTypeInstanceCapacityFree:
		err = instanceCapacityFreeSkuNameTemplate.Execute(nameBuffer, b)
	case constant.SkuTypeInstanceCapacityTier1:
		err = instanceCapacityTier1SkuNameTemplate.Execute(nameBuffer, b)
	case constant.SkuTypeInstanceCapacityTier2:
		err = instanceCapacityTier2SkuNameTemplate.Execute(nameBuffer, b)
	case constant.SkuTypeInstanceCapacityTier3:
		err = instanceCapacityTier3SkuNameTemplate.Execute(nameBuffer, b)
	case constant.SkuTypeInstanceCapacityTier4:
		err = instanceCapacityTier4SkuNameTemplate.Execute(nameBuffer, b)
	default:
		panic(fmt.Sprintf("invalid sku type: %v", skuType))
	}

	if err != nil {
		panic(fmt.Sprintf("render sku name failed, type=%s,err=%s", skuType, err))
	}

	return nameBuffer.String()
}
