package billing2

import (
	"context"
	"time"

	"github.com/shopspring/decimal"
)

type PlanInfo struct {
	Plan      string     `json:"plan"`
	Status    string     `json:"status"`
	StartedAt *time.Time `json:"started_at"`
	ExpiredAt *time.Time `json:"expired_at"`
	ClosedAt  *time.Time `json:"closed_at"`
}

type TenantPlanInfo struct {
	TenantID          uint            `json:"tenant_id"`
	EffectivePlan     string          `json:"effective_plan"`
	EffectiveDiscount decimal.Decimal `json:"effective_discount"`
	POCCredits        decimal.Decimal `json:"poc_credits"`
	DevTierPlanInfo   *PlanInfo       `json:"dev_tier_plan_info"`
}

type Price struct {
	CostPrice decimal.Decimal `json:"cost_price"`
	RawPrice  decimal.Decimal `json:"raw_price"`
}

type CostExplorerResult struct {
	InvoiceCosts Price `json:"invoice_costs"`
	CreditsCosts Price `json:"credits_costs"`
	TotalCosts   Price `json:"total_costs"`
}

type AzureAccessToken struct {
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	ExpiresIn   int    `json:"expires_in"`
}

type TenantID struct {
	TenantID uint `json:"tenant_id"`
}

type AliyunSubscriptionRecord struct {
	AliUid       string `json:"ali_uid"`
	BizId        string `json:"biz_id"`
	InTrial      bool   `json:"in_trial"`
	IsSubscribed bool   `json:"is_subscribed"`
	ProductCode  string `json:"product_code"`
	IsThirdParty bool   `json:"is_third_party"`
}

type AWSSubscriptionRecord struct {
	ProductCode        string `json:"product_code"`
	CustomerIdentifier string `json:"customer_identifier"`
	InTrial            bool   `json:"in_trial"`
	IsSubscribed       bool   `json:"is_subscribed"`
}

type NotifyRegistrationSourceReq struct {
	TenantID                  uint64 `json:"tenant_id"`
	WebsiteReferrerUrl        string `json:"website_referrer_url"`
	UtmCampaign               string `json:"utm_campaign"`
	UtmContent                string `json:"utm_content"`
	UtmMedium                 string `json:"utm_medium"`
	UtmSource                 string `json:"utm_source"`
	UtmTerm                   string `json:"utm_term"`
	MostRecentReferralUrl     string `json:"most_recent_referral_url"`
	SignupSource              string `json:"signup_source"`
	ProviderSource            string `json:"provider_source"`
	ThirdPartyAccountProvider string `json:"third_party_account_provider"`
	ThirdPartyAccountCode     string `json:"third_party_account_code"`
}

type TenantPromotionStatus struct {
	TenantID    uint `json:"tenant_id"`
	IsPromotion bool `json:"is_promotion"`
}

type BillingResource struct {
	Type       string      `json:"type"`
	InstanceID *string     `json:"instance_id"`
	Region     *string     `json:"region"`
	Provider   *string     `json:"provider"`
	IsFree     bool        `json:"is_free"`
	Origin     interface{} `json:"origin"`
}

type BillingActionInfo struct {
	Resource BillingResource `json:"resource"`
	Action   string          `json:"action"`
}

type BillingActionCheckResult struct {
	Pass     bool        `json:"pass"`
	Reason   *string     `json:"reason"`
	Original interface{} `json:"original"`
}

type BillingHandler interface {
	GetTenantPlanInfo(ctx context.Context, tenantID uint64) (*TenantPlanInfo, error)
	GetMonthlyBills(ctx context.Context, tenantID uint64, year int, month time.Month) (*CostExplorerResult, error)
	// for aliyun subscription management
	CreateAliyunSubscriptionRecord(ctx context.Context, aliUid string, bizId string, inTrial bool, productCode string) (*AliyunSubscriptionRecord, error)
	InactiveAliyunSubscriptionRecord(ctx context.Context, bizId string) (*AliyunSubscriptionRecord, error)
	GetAliyunSubscriptionRecordByBizId(ctx context.Context, bizId string) (*AliyunSubscriptionRecord, error)
	GetActiveSubscriptionRecordByAliUid(ctx context.Context, aliUid string) (*AliyunSubscriptionRecord, error)

	GetAzureAccessToken(ctx context.Context) (*AzureAccessToken, error)
	// for aws subscription
	CreateOrActiveAWSSubscriptionRecord(ctx context.Context, productCode string, customerIdentifier string, inTrial bool) (*AWSSubscriptionRecord, error)
	InactiveAWSSubscriptionRecord(ctx context.Context, productCode string, customerIdentifier string) (*AWSSubscriptionRecord, error)
	GetAWSSubscriptionFreeTrialStatus(ctx context.Context, accountCode string) (bool, error)
	NotifyRegistrationSource(ctx context.Context, req *NotifyRegistrationSourceReq) error
	GetTenantPromotionStatus(ctx context.Context, tenantID uint64) (*TenantPromotionStatus, error)
	BillingActionCheck(ctx context.Context, tenantID uint64, actionInfo *BillingActionInfo) (*BillingActionCheckResult, error)
}

var global BillingHandler = &BillingHandlerImpl{}

func GetHandler() BillingHandler {
	return global
}

func SetHandler(handler BillingHandler) {
	global = handler
}

const AccountIDHeader = "X-ACCOUNT-USER-ID"
const NeedPermissionCheckHeader = "X-BILLING-NEED-PERMISSION-CHECK"
const RequestSource = "X-BILLING-REQUEST-SOURCE"

const RequestSourceOps = "ops"
const RequestSourceConsole = "console"
