package billing

import (
	"context"

	"github.com/shopspring/decimal"

	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

const (
	OrgRoleOwner        = "owner"
	OrgRoleMember       = "member"
	OrgRoleBillingAdmin = "billing_admin"
	OrgRoleAuditAdmin   = "audit_admin"

	ProjectRoleOwner    = "project_owner"
	ProjectRoleDev      = "project_developer"
	ProjectRoleReadOnly = "project_readonly"
)

type ServerlessSpendLimitBizData struct {
	FreeCredits        decimal.Decimal `json:"free_credits"` // For Set FreeCredit
	InvoiceLimit       decimal.Decimal `json:"invoice_limit"`
	RemainingCredits   decimal.Decimal `json:"remaining_credits"`
	ActiveTotalCredits decimal.Decimal `json:"active_total_credits"` // For Query FreeCredit
	RechargePlanID     uint            `json:"recharge_plan_id"`     // For regional FreeCredit
}

type SpendLimitSetting struct {
	SpendLimitSettingID uint64          `json:"spendlimit_setting_id"`
	TenantID            uint64          `json:"tenant_id"`
	Interval            string          `json:"interval"`
	CostType            string          `json:"cost_type"`
	RangeType           string          `json:"range_type"`
	RangeID             uint64          `json:"range_id"`
	Limit               decimal.Decimal `json:"limit"`
	Status              string          `json:"status"`
	BizType             string          `json:"biz_type"`
	BizData             string          `json:"biz_data"`
}

type ResourceType string

const ResourceTypeServerlessCluster ResourceType = "serverless_cluster"

type ProviderEnum string

const ProviderAlicloud ProviderEnum = "Alicloud"

type Resource struct {
	Type     ResourceType  `json:"type"`
	Provider *ProviderEnum `json:"provider"`
}

type Action string

const ActionCreate Action = "add"

type ActionCheckResult struct {
	Pass   bool    `json:"pass"`
	Reason *string `json:"reason"`
}

//go:generate go run go.uber.org/mock/mockgen@latest -source=$GOFILE -package=mock_$GOPACKAGE -destination=./mock_$GOPACKAGE/mock_$GOFILE
type Client interface {
	// UNC stands for User Notification Center.
	SendClusterEventToUNC(ctx context.Context, tenantID uint64, event *UNCEvent) bizerr.BizError
	GetSpendLimitSettings(ctx context.Context, tenantId uint64) ([]*SpendLimitSetting, bizerr.BizError)
	BillingActionCheck(
		ctx context.Context,
		action Action,
		tenantID uint64,
		resource *Resource,
	) (*ActionCheckResult, bizerr.BizError)
}

// Refer to [https://pingcap-cn.feishu.cn/wiki/RtDLw6QPriA9Vpke0wGc0sb9nDc].
type UNCEvent struct {
	// Ops template identifier info.
	TriggerID  string `json:"trigger_id"`
	WorkFlowID string `json:"worker_flow_id"`

	// Content.
	Payload map[string]string `json:"payload"`

	// Target.
	// Organization("ORG") or project("PROJECT") scope.
	ScopeType string `json:"scope_type"`
	// Org ID or project ID. The length must be 1.
	TargetIDList []string `json:"target_id_list"`
	// Org roles or project roles.
	Roles []string `json:"roles"`

	IsSendNow bool   `json:"is_send_now"`
	IsTest    bool   `json:"is_test"`
	Operator  string `json:"operator"`
}
