package service

import (
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
)

// InstanceCapacityTier defines a pricing tier range for instance capacity billing.
type InstanceCapacityTier struct {
	SkuType constant.SkuType
	Min     int64 // inclusive lower bound
	Max     int64 // inclusive upper bound (0 = unlimited)
}

// buildTiers constructs the graduated tier configuration using the given free tier limit.
// The remaining tier boundaries are derived relative to the free limit to keep the same
// bracket sizes (4900, 95000, 400000, 500000).
func buildTiers(freeTierLimit int64) []InstanceCapacityTier {
	// Compute tier boundaries relative to the free tier limit,
	// keeping the same bracket sizes as the default (100/5000/100k/500k/1M).
	t1End := freeTierLimit + constant.InstanceCapacityTier1Limit - constant.InstanceCapacityFreeLimit
	t2End := freeTierLimit + constant.InstanceCapacityTier2Limit - constant.InstanceCapacityFreeLimit
	t3End := freeTierLimit + constant.InstanceCapacityTier3Limit - constant.InstanceCapacityFreeLimit

	return []InstanceCapacityTier{
		{constant.SkuTypeInstanceCapacityFree, 1, freeTierLimit},
		{constant.SkuTypeInstanceCapacityTier1, freeTierLimit + 1, t1End},
		{constant.SkuTypeInstanceCapacityTier2, t1End + 1, t2End},
		{constant.SkuTypeInstanceCapacityTier3, t2End + 1, t3End},
		{constant.SkuTypeInstanceCapacityTier4, t3End + 1, 0}, // 0 = unlimited
	}
}

// SplitIntoTiers splits totalCount into billable counts per tier.
// freeTierLimit controls how many instances fall into the free tier (default: constant.InstanceCapacityFreeLimit).
// Returns map[tier_sku_type] → count of instances in that tier.
// Only tiers with count > 0 are included.
func SplitIntoTiers(totalCount, freeTierLimit int64) map[constant.SkuType]int64 {
	if totalCount <= 0 {
		return nil
	}

	if freeTierLimit <= 0 {
		freeTierLimit = constant.InstanceCapacityFreeLimit
	}

	tiers := buildTiers(freeTierLimit)
	result := make(map[constant.SkuType]int64)
	remaining := totalCount

	for _, tier := range tiers {
		if remaining <= 0 {
			break
		}

		tierCapacity := tier.Max - tier.Min + 1
		if tier.Max == 0 {
			// unlimited tier — all remaining go here
			result[tier.SkuType] = remaining
			break
		}

		// How many instances fall into this tier
		countInTier := remaining
		if countInTier > tierCapacity {
			countInTier = tierCapacity
		}

		if countInTier > 0 {
			result[tier.SkuType] = countInTier
		}
		remaining -= countInTier
	}

	return result
}
