package datainit

import (
	"github.com/pingcap/dbaas/billing2/db/entity"
	"github.com/pingcap/dbaas/billing2/model/billingconfig"

	"time"

	"github.com/pingcap/dbaas/billing2/config"
	"github.com/pingcap/dbaas/billing2/forms"
	"github.com/pingcap/dbaas/billing2/model/billing"
	"github.com/pingcap/dbaas/billing2/model/payment"
	"github.com/pingcap/dbaas/billing2/model/payment/paymentsub"
	"github.com/pingcap/dbaas/billing2/utils/panicIf"
	"github.com/pingcap/dbaas/billing2/utils/tests"
	"github.com/shopspring/decimal"
)

const TestUnit = "test_unit"
const NoUsePackageId = 888

var BillingDate = time.Date(2021, 11, 1, 0, 0, 0, 0, time.UTC)
var billingConfigID uint = 1

func CreatePricePackageAndBind(tenantID uint) error {
	_, err := (&billing.UnitModel{}).CreateUnit(&forms.UnitInfo{
		UnitKey:   TestUnit,
		Price:     decimal.NewFromInt(1),
		PriceType: entity.PriceType_Normal,
	})
	if err != nil {
		return err
	}

	if err != nil {
		return err
	}
	_, err = (&billing.BindedPackageModel{}).BindPackageExtra(tenantID, &forms.BindedPackageInfoInput{
		PackageID:             NoUsePackageId,
		DiscountEnabled:       true,
		Internal:              false,
		InvoicePayable:        true,
		BindedBillingConfigID: &billingConfigID,
	})
	if err != nil {
		return err
	}
	return nil
}

func CreateMeasuresWithTime(tenantID uint, date time.Time) error {
	err := CreatePaymentMock(tenantID)
	if err != nil {
		return err
	}
	err = CreatePricePackageAndBind(tenantID)
	if err != nil {
		return err
	}

	err = SendMeasureWithTime(tenantID, date, 1)
	if err != nil {
		return err
	}
	return nil
}

func SendMeasureWithTime(tenantID uint, date time.Time, cost int) error {
	measureModel := &billing.MeasureModel{}
	_, err := measureModel.CostUnits(tenantID, &forms.UnitCosts{
		CostTimeStamp: date.Unix(),
		Unit:          TestUnit,
		Cost:          cost,
	})
	if err != nil {
		return err
	}
	return nil
}

func CreateMeasures(tenantID uint) error {
	return CreateMeasuresWithTime(tenantID, BillingDate)
}

func CreateInvoice(tenantID uint) (*forms.Invoice, error) {
	err := CreateMeasures(tenantID)
	if err != nil {
		return nil, err
	}
	invoiceModel := &payment.InvoiceModel{}
	billingConfigID, err := (&billingconfig.BillingConfigModel{}).GetUseBillingConfigIDByTimeStampWithCache(tenantID, BillingDate.Unix())
	if err != nil {
		return nil, err
	}
	info, err := invoiceModel.CreateMonthlyInvoice(tenantID, billingConfigID, BillingDate)
	if err != nil {
		return nil, err
	}
	return info, nil
}

func CreateCompany() error {
	err := (&paymentsub.BillingInformationModel{}).CreateBillingCompany(&forms.BillingCompany{
		CompanyKey:     config.Get().GetString(config.DefaultBillingCompanyKey),
		Name:           "PINGCAP",
		PaymentSubCode: "",
	})

	if err != nil {
		return err
	}
	return nil
}
func CreatePaymentMock(tenantID uint) error {
	tests.MockPaymentHandler()
	tests.MockCentralHandler()
	err := CreateCompany()
	if err != nil {
		return err
	}

	_, err = (&paymentsub.PaymentModel{}).CreatePaymentMethodAndActive(
		tenantID,
		&forms.PaymentMethodCreateQuery{
			PaymentType:           "mock",
			BindedBillingConfigID: &billingConfigID,
		},
	)
	return err
}
func CreateBillingConfig(tenantID uint, configType string) (*forms.BillingConfig, error) {
	startActiveTime := BillingDate.AddDate(0, -1, 0)
	return (&billingconfig.BillingConfigModel{}).CreateBillingConfigAndActive(
		forms.BillingConfig{
			TenantID:        tenantID,
			StartActiveTime: &startActiveTime,
			Type:            configType},
	)
}

func CreateTenantBillingInfo(tenantID uint) {
	tests.MockCentralHandler()
	_, err := (&paymentsub.BillingInformationModel{}).CreateOrUpdateBillingInfo(tenantID,
		&forms.BillingInformation{
			BillingAddress: forms.BillingAddress{Line1: "2469 Chicago Avenue",
				City:        "Fresno",
				State:       "CA",
				CountryCode: "US",
				PostalCode:  "93721",
			},
			TaxInfo: forms.TaxInfo{
				TaxIDType: "eu_vat",
				TaxID:     "ATU12345678",
			},
		},
	)
	panicIf.Error(err)
}
