package model

import (
	"encoding/json"
	"strconv"
	"time"

	"gorm.io/gorm"
)

// IotCard IoT 卡模型
// 物联网卡/流量卡的统一管理实体
// 通过 shop_id 区分所有权：NULL=平台所有，有值=店铺所有
type IotCard struct {
	gorm.Model
	BaseModel                          `gorm:"embedded"`
	ICCID                              string     `gorm:"column:iccid;type:varchar(20);uniqueIndex:idx_iot_card_iccid,where:deleted_at IS NULL;not null;comment:ICCID(唯一标识,电信19位/其他20位)" json:"iccid"`
	CardCategory                       string     `gorm:"column:card_category;type:varchar(20);default:'normal';not null;comment:卡业务类型 normal-普通卡 industry-行业卡" json:"card_category"`
	CarrierID                          uint       `gorm:"column:carrier_id;index;not null;comment:运营商ID" json:"carrier_id"`
	CarrierType                        string     `gorm:"column:carrier_type;type:varchar(20);comment:运营商类型(CMCC/CUCC/CTCC/CBN)，导入时快照" json:"carrier_type"`
	CarrierName                        string     `gorm:"column:carrier_name;type:varchar(100);comment:运营商名称，导入时快照" json:"carrier_name"`
	IMSI                               string     `gorm:"column:imsi;type:varchar(50);comment:IMSI" json:"imsi"`
	MSISDN                             string     `gorm:"column:msisdn;type:varchar(20);comment:MSISDN(手机号码)" json:"msisdn"`
	BatchNo                            string     `gorm:"column:batch_no;type:varchar(100);comment:批次号" json:"batch_no"`
	Supplier                           string     `gorm:"column:supplier;type:varchar(255);comment:供应商" json:"supplier"`
	Status                             int        `gorm:"column:status;type:int;default:1;not null;comment:状态 1-在库 2-已分销 3-已激活 4-已停用" json:"status"`
	ShopID                             *uint      `gorm:"column:shop_id;index;comment:店铺ID(NULL=平台所有,有值=店铺所有)" json:"shop_id,omitempty"`
	ActivatedAt                        *time.Time `gorm:"column:activated_at;comment:激活时间" json:"activated_at"`
	ActivationStatus                   int        `gorm:"column:activation_status;type:int;default:0;not null;comment:激活状态 0-未激活 1-已激活" json:"activation_status"`
	RealNameStatus                     int        `gorm:"column:real_name_status;type:int;default:0;not null;comment:实名状态 0-未实名 1-已实名" json:"real_name_status"`
	NetworkStatus                      int        `gorm:"column:network_status;type:int;default:0;not null;comment:网络状态 0-停机 1-开机" json:"network_status"`
	DataUsageMB                        int64      `gorm:"column:data_usage_mb;type:bigint;default:0;comment:累计流量使用(MB)" json:"data_usage_mb"`
	CurrentMonthUsageMB                float64    `gorm:"column:current_month_usage_mb;type:decimal(10,2);default:0;comment:系统自然月累计流量(MB，不等于运营商周期口径)" json:"current_month_usage_mb"`
	CurrentMonthStartDate              *time.Time `gorm:"column:current_month_start_date;type:date;comment:本月开始日期 - 用于检测跨月流量重置" json:"current_month_start_date"`
	LastMonthTotalMB                   float64    `gorm:"column:last_month_total_mb;type:decimal(10,2);default:0;comment:上月结束时的总流量(MB) - 用于跨月流量计算" json:"last_month_total_mb"`
	EnablePolling                      bool       `gorm:"column:enable_polling;type:boolean;default:true;comment:是否参与轮询 true-参与 false-不参与" json:"enable_polling"`
	LastDataCheckAt                    *time.Time `gorm:"column:last_data_check_at;comment:最后一次流量检查时间" json:"last_data_check_at"`
	LastRealNameCheckAt                *time.Time `gorm:"column:last_real_name_check_at;comment:最后一次实名检查时间" json:"last_real_name_check_at"`
	RealnameReversalCount              int        `gorm:"column:realname_reversal_count;type:int;default:0;not null;comment:实名逆转连续观测次数" json:"realname_reversal_count"`
	RealnameReversalStartedAt          *time.Time `gorm:"column:realname_reversal_started_at;comment:实名逆转当前确认窗口开始时间" json:"realname_reversal_started_at,omitempty"`
	LastProtectCheckAt                 *time.Time `gorm:"column:last_protect_check_at;comment:上次保护期一致性检查时间" json:"last_protect_check_at"`
	LastCardStatusCheckAt              *time.Time `gorm:"column:last_card_status_check_at;comment:最后一次卡状态检查时间" json:"last_card_status_check_at"`
	LastSyncTime                       *time.Time `gorm:"column:last_sync_time;comment:最后一次与Gateway同步时间" json:"last_sync_time"`
	SeriesID                           *uint      `gorm:"column:series_id;index;comment:套餐系列ID(关联PackageSeries)" json:"series_id,omitempty"`
	AccumulatedRechargeBySeriesJSON    string     `gorm:"column:accumulated_recharge_by_series;type:jsonb;default:'{}';comment:按套餐系列追踪的累计充值金额" json:"-"`
	FirstRechargeTriggeredBySeriesJSON string     `gorm:"column:first_recharge_triggered_by_series;type:jsonb;default:'{}';comment:按套餐系列追踪的首充触发状态" json:"-"`

	// 任务 24.1: 停复机相关字段
	FirstRealnameAt      *time.Time `gorm:"column:first_realname_at;comment:首次实名时间(用于触发首次实名激活)" json:"first_realname_at,omitempty"`
	StoppedAt            *time.Time `gorm:"column:stopped_at;comment:停机时间" json:"stopped_at,omitempty"`
	ResumedAt            *time.Time `gorm:"column:resumed_at;comment:最近复机时间" json:"resumed_at,omitempty"`
	StopReason           string     `gorm:"column:stop_reason;type:varchar(50);comment:停机原因(traffic_exhausted=流量耗尽,manual=手动停机,arrears=欠费)" json:"stop_reason,omitempty"`
	AssetStatus          int        `gorm:"column:asset_status;type:int;not null;default:1;comment:业务状态 1-在库 2-已销售 3-已换货 4-已停用" json:"asset_status"`
	Generation           int        `gorm:"column:generation;type:int;not null;default:1;comment:资产世代编号" json:"generation"`
	IsStandalone         bool       `gorm:"column:is_standalone;type:boolean;default:true;not null;comment:是否为独立卡(未绑定设备) 由触发器自动维护" json:"is_standalone"`
	VirtualNo            string     `gorm:"column:virtual_no;type:varchar(50);uniqueIndex:idx_iot_card_virtual_no,where:deleted_at IS NULL AND virtual_no IS NOT NULL AND virtual_no <> '';comment:虚拟号(可选，非空时全局唯一)" json:"virtual_no,omitempty"`
	DeviceVirtualNo      string     `gorm:"column:device_virtual_no;type:varchar(100);not null;default:'';comment:绑定设备的虚拟号快照(未绑定时为空字符串)" json:"device_virtual_no"`
	LastGatewayReadingMB float64    `gorm:"column:last_gateway_reading_mb;type:float;not null;default:0;comment:运营商当前周期累计流量读数(MB，来自网关)" json:"last_gateway_reading_mb"`
	GatewayExtend        string     `gorm:"column:gateway_extend;type:text;not null;default:'';comment:Gateway 卡状态扩展字段，原样保存上游 extend，用于展示运营商侧实际停机原因" json:"gateway_extend"`
	// GatewayCardIMEI 为插拔卡业务中网关上报的设备 IMEI，非设备自身 IMEI，仅用于数据同步落库
	GatewayCardIMEI string `gorm:"column:gateway_card_imei;type:varchar(50);not null;default:'';comment:插拔卡业务 IMEI，网关卡状态接口同步，非设备 IMEI" json:"gateway_card_imei"`
	RealnamePolicy  string `gorm:"column:realname_policy;type:varchar(20);default:'after_order';not null;comment:实名认证策略(none=无需实名,before_order=先实名后充值/购买,after_order=先充值/购买后实名)" json:"realname_policy"`

	// ICCID 双列存储，用于支持 19/20 位 ICCID 精确路由查询
	// 所有卡必须有 ICCID19；仅 20 位运营商卡有 ICCID20（19 位卡为 nil → 数据库 NULL）
	ICCID19 string  `gorm:"column:iccid_19;type:varchar(19);comment:ICCID前19位（所有卡必填，用于19位运营商精确查询）" json:"iccid_19,omitempty"`
	ICCID20 *string `gorm:"column:iccid_20;type:varchar(20);comment:完整20位ICCID(仅20位运营商卡有值，19位卡为NULL)" json:"iccid_20,omitempty"`
}

// TableName 指定表名
func (IotCard) TableName() string {
	return "tb_iot_card"
}

func (c *IotCard) GetAccumulatedRechargeBySeriesMap() (map[uint]int64, error) {
	result := make(map[uint]int64)
	if c.AccumulatedRechargeBySeriesJSON == "" || c.AccumulatedRechargeBySeriesJSON == "{}" {
		return result, nil
	}
	var raw map[string]int64
	if err := json.Unmarshal([]byte(c.AccumulatedRechargeBySeriesJSON), &raw); err != nil {
		return nil, err
	}
	for k, v := range raw {
		id, err := strconv.ParseUint(k, 10, 64)
		if err != nil {
			continue
		}
		result[uint(id)] = v
	}
	return result, nil
}

func (c *IotCard) SetAccumulatedRechargeBySeriesMap(m map[uint]int64) error {
	raw := make(map[string]int64)
	for k, v := range m {
		raw[strconv.FormatUint(uint64(k), 10)] = v
	}
	data, err := json.Marshal(raw)
	if err != nil {
		return err
	}
	c.AccumulatedRechargeBySeriesJSON = string(data)
	return nil
}

func (c *IotCard) GetAccumulatedRechargeBySeries(seriesID uint) int64 {
	m, err := c.GetAccumulatedRechargeBySeriesMap()
	if err != nil {
		return 0
	}
	return m[seriesID]
}

func (c *IotCard) AddAccumulatedRechargeBySeries(seriesID uint, amount int64) error {
	m, err := c.GetAccumulatedRechargeBySeriesMap()
	if err != nil {
		m = make(map[uint]int64)
	}
	m[seriesID] += amount
	return c.SetAccumulatedRechargeBySeriesMap(m)
}

func (c *IotCard) GetFirstRechargeTriggeredBySeriesMap() (map[uint]bool, error) {
	result := make(map[uint]bool)
	if c.FirstRechargeTriggeredBySeriesJSON == "" || c.FirstRechargeTriggeredBySeriesJSON == "{}" {
		return result, nil
	}
	var raw map[string]bool
	if err := json.Unmarshal([]byte(c.FirstRechargeTriggeredBySeriesJSON), &raw); err != nil {
		return nil, err
	}
	for k, v := range raw {
		id, err := strconv.ParseUint(k, 10, 64)
		if err != nil {
			continue
		}
		result[uint(id)] = v
	}
	return result, nil
}

func (c *IotCard) SetFirstRechargeTriggeredBySeriesMap(m map[uint]bool) error {
	raw := make(map[string]bool)
	for k, v := range m {
		raw[strconv.FormatUint(uint64(k), 10)] = v
	}
	data, err := json.Marshal(raw)
	if err != nil {
		return err
	}
	c.FirstRechargeTriggeredBySeriesJSON = string(data)
	return nil
}

func (c *IotCard) IsFirstRechargeTriggeredBySeries(seriesID uint) bool {
	m, err := c.GetFirstRechargeTriggeredBySeriesMap()
	if err != nil {
		return false
	}
	return m[seriesID]
}

func (c *IotCard) SetFirstRechargeTriggeredBySeries(seriesID uint, triggered bool) error {
	m, err := c.GetFirstRechargeTriggeredBySeriesMap()
	if err != nil {
		m = make(map[uint]bool)
	}
	m[seriesID] = triggered
	return c.SetFirstRechargeTriggeredBySeriesMap(m)
}
