package model

import (
	"encoding/json"
	"time"

	"gorm.io/gorm"
)

// PackageSeries 套餐系列模型
// 套餐的分组,用于一次性分佣规则配置
type PackageSeries struct {
	gorm.Model
	BaseModel                   `gorm:"embedded"`
	SeriesCode                  string `gorm:"column:series_code;type:varchar(100);uniqueIndex:idx_package_series_code,where:deleted_at IS NULL;not null;comment:系列编码" json:"series_code"`
	SeriesName                  string `gorm:"column:series_name;type:varchar(255);not null;comment:系列名称" json:"series_name"`
	Description                 string `gorm:"column:description;type:text;comment:描述" json:"description"`
	Status                      int    `gorm:"column:status;type:int;default:1;not null;comment:状态 0=禁用 1=启用" json:"status"`
	OneTimeCommissionConfigJSON string `gorm:"column:one_time_commission_config;type:jsonb;default:'{}';comment:一次性佣金规则配置" json:"-"`
	EnableOneTimeCommission     bool   `gorm:"column:enable_one_time_commission;default:false;comment:是否启用一次性佣金（顶层字段，支持SQL索引）" json:"enable_one_time_commission"`
}

// TableName 指定表名
func (PackageSeries) TableName() string {
	return "tb_package_series"
}

// Package 套餐模型
// 只适用于 IoT 卡,支持真流量/虚流量共存机制
type Package struct {
	gorm.Model
	BaseModel            `gorm:"embedded"`
	PackageCode          string `gorm:"column:package_code;type:varchar(100);uniqueIndex:idx_package_code,where:deleted_at IS NULL;not null;comment:套餐编码" json:"package_code"`
	PackageName          string `gorm:"column:package_name;type:varchar(255);not null;comment:套餐名称" json:"package_name"`
	SeriesID             uint   `gorm:"column:series_id;index;comment:套餐系列ID" json:"series_id"`
	PackageType          string `gorm:"column:package_type;type:varchar(50);not null;comment:套餐类型 formal-正式套餐 addon-附加套餐" json:"package_type"`
	DurationMonths       int    `gorm:"column:duration_months;type:int;not null;comment:套餐时长(月数) 1-月套餐 12-年套餐" json:"duration_months"`
	RealDataMB           int64  `gorm:"column:real_data_mb;type:bigint;default:0;comment:真流量额度(MB)" json:"real_data_mb"`
	VirtualDataMB        int64  `gorm:"column:virtual_data_mb;type:bigint;default:0;comment:虚流量额度(MB，业务停机阈值)" json:"virtual_data_mb"`
	EnableVirtualData    bool   `gorm:"column:enable_virtual_data;type:boolean;default:false;not null;comment:是否启用虚流量" json:"enable_virtual_data"`
	Status               int    `gorm:"column:status;type:int;default:1;not null;comment:状态 0=禁用 1=启用" json:"status"`
	CostPrice            int64  `gorm:"column:cost_price;type:bigint;default:0;comment:成本价(分为单位)" json:"cost_price"`
	SuggestedRetailPrice int64  `gorm:"column:suggested_retail_price;type:bigint;default:0;comment:建议售价(分为单位)" json:"suggested_retail_price"`
	PriceConfigStatus    int    `gorm:"column:price_config_status;type:int;default:0;not null;comment:价格配置状态 0-未配置 1-赠送0价 2-已配置非0" json:"price_config_status"`
	IsGift               bool   `gorm:"column:is_gift;type:boolean;default:false;not null;comment:是否赠送套餐 true-赠送 false-普通可售" json:"is_gift"`
	ShelfStatus          int    `gorm:"column:shelf_status;type:int;default:2;not null;comment:上架状态 1-上架 2-下架" json:"shelf_status"`
	CalendarType         string `gorm:"column:calendar_type;type:varchar(20);default:'by_day';comment:套餐周期类型 natural_month-自然月 by_day-按天" json:"calendar_type"`
	DurationDays         int    `gorm:"column:duration_days;type:int;comment:套餐天数(calendar_type=by_day时必填)" json:"duration_days"`
	DataResetCycle       string `gorm:"column:data_reset_cycle;type:varchar(20);default:'monthly';comment:流量重置周期 daily-每日 monthly-每月 yearly-每年 none-不重置" json:"data_reset_cycle"`
	// ExpiryBase 到期时间基准：from_activation-实名激活时起算，from_purchase-购买时起算
	ExpiryBase   string  `gorm:"column:expiry_base;type:varchar(30);not null;default:'from_activation';comment:到期时间基准 from_activation-实名激活时起算 from_purchase-购买时起算" json:"expiry_base"`
	VirtualRatio float64 `gorm:"column:virtual_ratio;type:decimal(18,6);default:1.0;comment:展示倍率(real_data_mb/virtual_data_mb)，创建套餐时计算存储" json:"virtual_ratio"`
}

// TableName 指定表名
func (Package) TableName() string {
	return "tb_package"
}

// PackageUsage 套餐使用情况模型
// 跟踪单卡套餐和设备级套餐的流量使用
type PackageUsage struct {
	gorm.Model
	BaseModel                 `gorm:"embedded"`
	OrderID                   uint       `gorm:"column:order_id;index;not null;comment:订单ID" json:"order_id"`
	OrderNo                   string     `gorm:"column:order_no;type:varchar(30);not null;default:'';comment:订单号快照（从订单复制）" json:"order_no"`
	RefundID                  *uint      `gorm:"column:refund_id;index;comment:退款单ID快照（退款后写入）" json:"refund_id,omitempty"`
	RefundNo                  string     `gorm:"column:refund_no;type:varchar(50);not null;default:'';comment:退款单号快照（退款后写入）" json:"refund_no"`
	PackageID                 uint       `gorm:"column:package_id;index;not null;comment:套餐ID" json:"package_id"`
	UsageType                 string     `gorm:"column:usage_type;type:varchar(20);not null;comment:使用类型 single_card-单卡套餐 device-设备级套餐" json:"usage_type"`
	IotCardID                 uint       `gorm:"column:iot_card_id;index;comment:IoT卡ID(单卡套餐时有值)" json:"iot_card_id"`
	DeviceID                  uint       `gorm:"column:device_id;index;comment:设备ID(设备级套餐时有值)" json:"device_id"`
	DataLimitMB               int64      `gorm:"column:data_limit_mb;type:bigint;not null;comment:真总量快照(MB)" json:"data_limit_mb"`
	DataUsageMB               int64      `gorm:"column:data_usage_mb;type:bigint;default:0;comment:真已用(MB)" json:"data_usage_mb"`
	VirtualTotalMBSnapshot    int64      `gorm:"column:virtual_total_mb_snapshot;type:bigint;default:0;comment:虚总量快照(MB，业务停机阈值)" json:"virtual_total_mb_snapshot"`
	DisplayGainRatioSnapshot  float64    `gorm:"column:display_gain_ratio_snapshot;type:decimal(18,6);default:1.0;comment:展示倍率快照(real_total_mb/virtual_total_mb)" json:"display_gain_ratio_snapshot"`
	EnableVirtualDataSnapshot bool       `gorm:"column:enable_virtual_data_snapshot;type:boolean;default:false;comment:是否启用虚流量快照" json:"enable_virtual_data_snapshot"`
	ExpiryBaseSnapshot        string     `gorm:"column:expiry_base_snapshot;type:varchar(30);not null;default:'';comment:购买时生效条件快照" json:"expiry_base_snapshot"`
	CalendarTypeSnapshot      string     `gorm:"column:calendar_type_snapshot;type:varchar(20);not null;default:'';comment:购买时周期类型快照" json:"calendar_type_snapshot"`
	DurationMonthsSnapshot    int        `gorm:"column:duration_months_snapshot;type:int;not null;default:0;comment:购买时月数快照" json:"duration_months_snapshot"`
	DurationDaysSnapshot      int        `gorm:"column:duration_days_snapshot;type:int;not null;default:0;comment:购买时天数快照" json:"duration_days_snapshot"`
	ActivatedAt               *time.Time `gorm:"column:activated_at;comment:套餐生效时间" json:"activated_at"`
	ExpiresAt                 *time.Time `gorm:"column:expires_at;comment:套餐过期时间" json:"expires_at"`
	Status                    int        `gorm:"column:status;type:int;default:1;not null;comment:状态 0-待生效 1-生效中 2-已用完 3-已过期 4-已失效" json:"status"`
	LastPackageCheckAt        *time.Time `gorm:"column:last_package_check_at;comment:最后一次套餐流量检查时间" json:"last_package_check_at"`
	Priority                  int        `gorm:"column:priority;type:int;default:1;index:idx_package_usage_priority;comment:优先级(主套餐和加油包按此字段排队,数字越小优先级越高)" json:"priority"`
	MasterUsageID             *uint      `gorm:"column:master_usage_id;type:bigint;index:idx_package_usage_master_usage_id;comment:主套餐使用记录ID(加油包关联主套餐,主套餐此字段为NULL)" json:"master_usage_id"`
	HasIndependentExpiry      bool       `gorm:"column:has_independent_expiry;type:boolean;default:false;comment:加油包是否有独立有效期(true-有独立到期时间 false-跟随主套餐)" json:"has_independent_expiry"`
	PendingRealnameActivation bool       `gorm:"column:pending_realname_activation;type:boolean;default:false;comment:是否等待实名激活(true-待实名后激活 false-已激活或不需实名)" json:"pending_realname_activation"`
	PackageName               string     `gorm:"column:package_name;type:varchar(255);not null;default:'';comment:套餐名称快照(从Package复制,用于历史记录展示)" json:"package_name"`
	PaidAmount                *int64     `gorm:"column:paid_amount;type:bigint;comment:购买实付金额快照（分，从订单 actual_paid_amount 复制，无订单或线下支付时为null）" json:"paid_amount,omitempty"`
	RetailAmount              *int64     `gorm:"column:retail_amount;type:bigint;comment:购买零售价快照（分，从订单 total_amount 复制，无订单关联时为null）" json:"retail_amount,omitempty"`
	PackagePriceConfigStatus  int        `gorm:"column:package_price_config_status;type:int;default:0;not null;comment:套餐价格配置状态快照 0-未配置 1-赠送0价 2-已配置非0" json:"package_price_config_status"`
	PackageIsGift             bool       `gorm:"column:package_is_gift;type:boolean;default:false;not null;comment:套餐是否赠送快照 true-赠送 false-普通可售" json:"package_is_gift"`
	DataResetCycle            string     `gorm:"column:data_reset_cycle;type:varchar(20);comment:流量重置周期(从Package复制,用于历史记录)" json:"data_reset_cycle"`
	LastResetAt               *time.Time `gorm:"column:last_reset_at;comment:最后一次流量重置时间" json:"last_reset_at"`
	NextResetAt               *time.Time `gorm:"column:next_reset_at;index:idx_package_usage_next_reset_at;comment:下次流量重置时间(用于定时任务查询)" json:"next_reset_at"`
	Generation                int        `gorm:"column:generation;type:int;not null;default:1;comment:资产世代编号" json:"generation"`
}

// TableName 指定表名
func (PackageUsage) TableName() string {
	return "tb_package_usage"
}

// PackageUsageDailyRecord 套餐流量日记录模型
// 记录每个套餐每天的流量使用情况，用于流量详单查询
type PackageUsageDailyRecord struct {
	ID                uint      `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
	PackageUsageID    uint      `gorm:"column:package_usage_id;not null;uniqueIndex:idx_package_usage_daily_record_unique;index:idx_package_usage_daily_record_date;comment:套餐使用记录ID" json:"package_usage_id"`
	Date              time.Time `gorm:"column:date;type:date;not null;uniqueIndex:idx_package_usage_daily_record_unique;comment:日期" json:"date"`
	DailyUsageMB      int       `gorm:"column:daily_usage_mb;type:int;default:0;comment:当日流量使用量(MB)" json:"daily_usage_mb"`
	CumulativeUsageMB int64     `gorm:"column:cumulative_usage_mb;type:bigint;default:0;comment:截止当日的累计流量(MB)" json:"cumulative_usage_mb"`
	CreatedAt         time.Time `gorm:"column:created_at;default:CURRENT_TIMESTAMP" json:"created_at"`
	UpdatedAt         time.Time `gorm:"column:updated_at;default:CURRENT_TIMESTAMP" json:"updated_at"`
}

// TableName 指定表名
func (PackageUsageDailyRecord) TableName() string {
	return "tb_package_usage_daily_record"
}

// OneTimeCommissionConfig 一次性佣金规则配置
type OneTimeCommissionConfig struct {
	Enable              bool                    `json:"enable"`
	TriggerType         string                  `json:"trigger_type"`
	Threshold           int64                   `json:"threshold"`
	CommissionType      string                  `json:"commission_type"`
	CommissionAmount    int64                   `json:"commission_amount"`
	Tiers               []OneTimeCommissionTier `json:"tiers,omitempty"`
	ValidityType        string                  `json:"validity_type"`
	ValidityValue       string                  `json:"validity_value"`
	EnableForceRecharge bool                    `json:"enable_force_recharge"`
	ForceCalcType       string                  `json:"force_calc_type"`
	ForceAmount         int64                   `json:"force_amount"`
}

// OneTimeCommissionTier 一次性佣金梯度配置
type OneTimeCommissionTier struct {
	Operator  string `json:"operator"` // 阈值比较运算符：>、>=、<、<=，空值默认 >=
	Dimension string `json:"dimension"`
	StatScope string `json:"stat_scope"`
	Threshold int64  `json:"threshold"`
	Amount    int64  `json:"amount"`
}

const (
	OneTimeCommissionTriggerFirstRecharge       = "first_recharge"
	OneTimeCommissionTriggerAccumulatedRecharge = "accumulated_recharge"

	OneTimeCommissionValidityPermanent = "permanent"
	OneTimeCommissionValidityFixedDate = "fixed_date"
	OneTimeCommissionValidityRelative  = "relative"

	OneTimeCommissionForceCalcFixed   = "fixed"
	OneTimeCommissionForceCalcDynamic = "dynamic"

	OneTimeCommissionStatScopeSelf       = "self"
	OneTimeCommissionStatScopeSelfAndSub = "self_and_sub"

	TierTypeSalesCount  = "sales_count"
	TierTypeSalesAmount = "sales_amount"
	// 阈值运算符常量
	TierOperatorGT  = ">"
	TierOperatorGTE = ">="
	TierOperatorLT  = "<"
	TierOperatorLTE = "<="
)

func (ps *PackageSeries) GetOneTimeCommissionConfig() (*OneTimeCommissionConfig, error) {
	if ps.OneTimeCommissionConfigJSON == "" {
		return nil, nil
	}
	var config OneTimeCommissionConfig
	if err := json.Unmarshal([]byte(ps.OneTimeCommissionConfigJSON), &config); err != nil {
		return nil, err
	}
	return &config, nil
}

func (ps *PackageSeries) SetOneTimeCommissionConfig(config *OneTimeCommissionConfig) error {
	if config == nil {
		ps.OneTimeCommissionConfigJSON = ""
		return nil
	}
	data, err := json.Marshal(config)
	if err != nil {
		return err
	}
	ps.OneTimeCommissionConfigJSON = string(data)
	return nil
}
