package datainit

import (
	"fmt"
	"time"

	"github.com/google/uuid"
	"github.com/pingcap/dbaas/billing2/constant"
	"github.com/pingcap/dbaas/billing2/db"
	"github.com/pingcap/dbaas/billing2/db/entity"
	"github.com/pingcap/dbaas/billing2/model/billingconfig"
	"github.com/pingcap/dbaas/billing2/utils/panicIf"
	"github.com/shopspring/decimal"
)

const (
	DefaultUnitCostsDedicatedAWSClusterID  = uint(1)
	DefaultUnitCostsDedicatedGCPClusterID  = uint(2)
	DefaultUnitCostsServerlessAWSClusterID = uint(10)

	DefaultUnitCostsProjectID = uint(1)
)

func CreateDefaultUserUnitCosts(tenantID uint, startBillingDate time.Time, durationDays int) {
	billingConfigID, err := (&billingconfig.BillingConfigModel{}).GetActiveBillingConfigID(tenantID)
	panicIf.Error(err)
	for i := 0; i != durationDays; i++ {
		billingDate := startBillingDate.AddDate(0, 0, i)
		costTimeStamp := billingDate.Unix()
		consumedSource := entity.ConsumedSource_Invoice
		if billingDate.Day() <= 10 {
			consumedSource = entity.ConsumedSource_Credits
		}
		for _, comp := range []string{constant.TiDBComp, constant.TiKVComp} {
			clusterIDs := []uint{DefaultUnitCostsDedicatedAWSClusterID, DefaultUnitCostsDedicatedGCPClusterID}
			for i, nodeUnit := range []string{AWSNodeUnit, GCPNodeUnit} {
				dedicatedClusterID := clusterIDs[i]
				ent := entity.UserUnitCost{
					CostID:                uuid.NewString(),
					TenantID:              tenantID,
					BindedBillingConfigID: billingConfigID,
					CostTimeStamp:         costTimeStamp,
					Unit:                  nodeUnit,
					CostPrice:             decimal.NewFromInt(1),
					RawPrice:              decimal.NewFromInt(2),
					Labels:                map[string]string{"component": comp, constant.ClusterLabelKey: fmt.Sprint(dedicatedClusterID), constant.ProjectLabelKey: fmt.Sprint(DefaultUnitCostsProjectID)},
					ConsumedSource:        consumedSource,
					Status:                entity.UserUnitCostStatus_DONE,
					Internal:              false,
				}
				panicIf.Error(ent.Create(db.GetDB()))
			}
		}
		costs := []entity.UserUnitCost{
			{
				CostID:                uuid.NewString(),
				TenantID:              tenantID,
				BindedBillingConfigID: billingConfigID,
				CostTimeStamp:         costTimeStamp,
				Unit:                  AWSDataTransferCrossAZUnit,
				CostPrice:             decimal.NewFromInt(2),
				RawPrice:              decimal.NewFromInt(2),
				Labels:                map[string]string{constant.ProjectLabelKey: fmt.Sprint(DefaultUnitCostsProjectID)},
				ConsumedSource:        consumedSource,
				Status:                entity.UserUnitCostStatus_DONE,
				Internal:              false,
			},
			{
				CostID:                uuid.NewString(),
				TenantID:              tenantID,
				BindedBillingConfigID: billingConfigID,
				CostTimeStamp:         costTimeStamp,
				Unit:                  AWSServerlessRUUnit,
				CostPrice:             decimal.NewFromInt(1),
				RawPrice:              decimal.NewFromInt(1),
				Labels:                map[string]string{constant.ClusterLabelKey: fmt.Sprint(DefaultUnitCostsServerlessAWSClusterID), constant.ProjectLabelKey: fmt.Sprint(DefaultUnitCostsProjectID)},
				ConsumedSource:        consumedSource,
				Status:                entity.UserUnitCostStatus_DONE,
				Internal:              billingDate.Day() <= 5,
			},
			{
				CostID:                uuid.NewString(),
				TenantID:              tenantID,
				BindedBillingConfigID: billingConfigID,
				CostTimeStamp:         costTimeStamp,
				Unit:                  AWSServerlessStorageUnit,
				CostPrice:             decimal.NewFromInt(1),
				RawPrice:              decimal.NewFromInt(1),
				Labels:                map[string]string{constant.ClusterLabelKey: fmt.Sprint(DefaultUnitCostsServerlessAWSClusterID), constant.ProjectLabelKey: fmt.Sprint(DefaultUnitCostsProjectID)},
				ConsumedSource:        consumedSource,
				Status:                entity.UserUnitCostStatus_DONE,
				Internal:              billingDate.Day() <= 5,
			},
		}
		for _, ent := range costs {
			panicIf.Error(ent.Create(db.GetDB()))
		}
	}
}
