package billing2

import (
	"time"

	"github.com/shopspring/decimal"
)

type ChangeBindedDiscountInput struct {
	BindedDiscount  *decimal.Decimal `json:"binded_discount"`
	ChangerTenantID uint             `json:"changer_tenant_id"`
	ChangerUserID   uint             `json:"changer_user_id"`
}

type CreditsChargeInfoInput struct {
	ChargeCount     decimal.Decimal `json:"charge_count"`
	ChargerTenantID uint            `json:"charger_tenant_id"`
	ChargerUserID   uint            `json:"charger_user_id"`
	ChargeReason    string          `json:"charge_reason"`
}

type CreditsChargeInfoMigrateInput struct {
	ChargeCount     decimal.Decimal `json:"charge_count"`
	ChargerTenantID uint            `json:"charger_tenant_id"`
	ChargerUserID   uint            `json:"charger_user_id"`
	ChargeReason    string          `json:"charge_reason"`
	ChargeTime      time.Time       `json:"charge_time"`
}

type CreditsChargeInfo struct {
	BindedPackageID uint            `json:"binded_package_id"`
	ChargeCount     decimal.Decimal `json:"charge_count"`
	ChargerTenantID uint            `json:"charger_tenant_id"`
	ChargerUserID   uint            `json:"charger_user_id"`
	ChargeReason    string          `json:"charge_reason"`
	ChargeTime      time.Time       `json:"charge_time"`
}

type CreditsChargeHistory struct {
	BindedPackageID uint                `json:"binded_package_id"`
	History         []CreditsChargeInfo `json:"history"`
	TotalAmounts    decimal.Decimal     `json:"total_amounts"`
}

type PaymentMethod struct {
	TenantID        uint   `json:"tenant_id"`
	PaymentMethodID uint   `json:"payment_method_id"`
	PaymentType     string `json:"payment_type"`
	PaymentCode     string `json:"payment_code"`
	Payable         bool   `json:"payable"`
}

type UnitCostsInput struct {
	//optional
	CostID        string            `json:"cost_id"`
	CostTimeStamp int64             `json:"cost_time_stamp"`
	Unit          string            `json:"unit"`
	Cost          int               `json:"cost"`
	Labels        map[string]string `json:"labels"`
}

const (
	PaymentType_AWS    = "aws"
	PaymentType_GCP    = "gcp"
	PaymentType_STRIPE = "stripe"
)

type BillingHandler interface {
	ChangeUserDiscount(tenantID, bindedPackageID uint64, input *ChangeBindedDiscountInput) error
	ChargeCredits(tenantID, bindedPackageID uint64, input *CreditsChargeInfoInput) error
	GetCredits(tenantID, bindedPackageID uint64) (*decimal.Decimal, error)
	GetCreditsHistory(tenantID, bindedPackageID uint64) (*CreditsChargeHistory, error)
	GetPackageDiscount(packageID uint64) (*decimal.Decimal, error)
	UpdatePackageDiscount(packageID uint64, discount decimal.Decimal) error
	GetBindedPackageDiscount(tenantID, bindedPackageID uint64) (*decimal.Decimal, error)
	UpdateBindedPackageDiscount(tenantID, bindedPackageID uint64, discount *decimal.Decimal) error
	BindPackage(tenantID, packageID uint64) (uint64, error)
	UnBindPackage(tenantID, bindedPackageID uint64) error
	ConfirmStripeSetupIntent(tenantID uint64) error
	CreatePayment(tenantID uint64, paymentType string) error
	ListPayments(tenantID uint64) ([]PaymentMethod, error)
	MeasureCosts(tenantID uint64, cost *UnitCostsInput) error
	MigratePayments() error
	MigrateInvoices() error
	MigrateChargeCredits(bindedPackageID uint64, records []CreditsChargeInfoMigrateInput) error
}

var global BillingHandler = &BillingHandlerImpl{}

func GetHandler() BillingHandler {
	return global
}

func SetHandler(handler BillingHandler) {
	global = handler
}
