package workers

import (
	"github.com/pingcap/dbaas/billing2/config"
	"github.com/pingcap/dbaas/billing2/db/entity"
	"github.com/pingcap/dbaas/billing2/forms"
	"github.com/pingcap/dbaas/billing2/model/billing"
	"github.com/pingcap/dbaas/billing2/model/billingconfig"
	"github.com/pingcap/dbaas/billing2/utils/log"
	"github.com/pingcap/dbaas/billing2/utils/pagination"
	"github.com/pingcap/dbaas/billing2/utils/timeutils"
	"go.uber.org/zap"
)

func BillingConfigScheduledExecution() {
	now := timeutils.GetNow()
	model := &billingconfig.BillingConfigModel{}
	billingConfigs, err := model.GetAllScheduledBillingConfigs()
	if err != nil {
		log.Error("worker BillingConfigScheduledExecution GetAllScheduledBillingConfigs error", zap.Error(err))
		return
	}
	for _, billingConfig := range billingConfigs {
		switch billingConfig.Status {
		case entity.BillingConfigStatus_Scheduled:
			if int(billingConfig.StartActiveTime.Sub(now).Minutes()) < config.Get().GetInt(config.BillingConfigActiveMinutes) {
				err = model.SwitchBillingConfig(billingConfig, false)
				if err != nil {
					log.Error("worker BillingConfigScheduledExecution SwitchBillingConfig error", zap.Error(err))
					continue
				}
			}

		case entity.BillingConfigStatus_Closing:
			if billingConfig.EndActiveTime == nil && billingConfig.ClosedTime == nil {
				log.Error("worker BillingConfigScheduledExecution billingConfig EndActiveTime error", zap.Any("billingConfig", billingConfig))
			}
			if billingConfig.EndActiveTime != nil && now.After(*billingConfig.EndActiveTime) {

				// deal contract
				var contractModel = &billing.ContractModel{}
				p := &pagination.Pagination{Page: 1, PageSize: 20}
				contracts, err := contractModel.ListUserViewContracts(billingConfig.TenantID, billingConfig.ID, p)
				if err == nil && len(*contracts.Contracts) > 0 {
					for _, contract := range *contracts.Contracts {
						contractAction := forms.ContractOperationInput{
							ContractID: contract.ID,
							Action:     entity.ContractActionCancel,
						}

						contractModel.OperateContractByAdmin(billingConfig.TenantID, &contractAction)
					}
				}
			}
			if billingConfig.ClosedTime != nil && now.After(*billingConfig.ClosedTime) {
				err = model.ClosedBillingConfig(billingConfig.TenantID, billingConfig.ID)
				if err != nil {
					log.Error("worker BillingConfigScheduledExecution ClosedBillingConfig error", zap.Error(err))
					continue
				}
			}
		}
	}
}
