-- 迁移: 账号与佣金管理模块数据模型变更
-- 变更ID: add-commission-model-changes
-- 说明: 
--   1. 扩展现有表字段
--   2. 创建企业卡授权表和资产分配记录表
--   3. 统一 owner_type 枚举值 (agent -> shop)

-- ========================================
-- 1. 扩展现有表字段
-- ========================================

-- 1.1 tb_commission_withdrawal_request 佣金提现申请表新增字段
ALTER TABLE tb_commission_withdrawal_request
ADD COLUMN IF NOT EXISTS withdrawal_no VARCHAR(50),
ADD COLUMN IF NOT EXISTS applicant_id BIGINT,
ADD COLUMN IF NOT EXISTS shop_id BIGINT,
ADD COLUMN IF NOT EXISTS fee_rate BIGINT DEFAULT 0,
ADD COLUMN IF NOT EXISTS payment_type VARCHAR(20) DEFAULT 'manual',
ADD COLUMN IF NOT EXISTS processor_id BIGINT,
ADD COLUMN IF NOT EXISTS processed_at TIMESTAMP WITH TIME ZONE,
ADD COLUMN IF NOT EXISTS remark TEXT;

-- 添加唯一索引（提现单号）
CREATE UNIQUE INDEX IF NOT EXISTS uk_commission_withdrawal_no 
ON tb_commission_withdrawal_request(withdrawal_no) WHERE deleted_at IS NULL AND withdrawal_no IS NOT NULL;

-- 添加字段注释
COMMENT ON COLUMN tb_commission_withdrawal_request.withdrawal_no IS '提现单号（唯一，格式：W + 时间戳 + 随机数）';
COMMENT ON COLUMN tb_commission_withdrawal_request.applicant_id IS '申请人账号ID';
COMMENT ON COLUMN tb_commission_withdrawal_request.shop_id IS '店铺ID（冗余字段）';
COMMENT ON COLUMN tb_commission_withdrawal_request.fee_rate IS '手续费比率（基点，100=1%，快照）';
COMMENT ON COLUMN tb_commission_withdrawal_request.payment_type IS '放款类型（manual=人工打款）';
COMMENT ON COLUMN tb_commission_withdrawal_request.processor_id IS '处理人ID';
COMMENT ON COLUMN tb_commission_withdrawal_request.processed_at IS '处理时间';
COMMENT ON COLUMN tb_commission_withdrawal_request.remark IS '备注';

-- 1.2 tb_account 账号表新增字段
ALTER TABLE tb_account
ADD COLUMN IF NOT EXISTS is_primary BOOLEAN DEFAULT FALSE;

COMMENT ON COLUMN tb_account.is_primary IS '是否为店铺主账号（默认 false）';

-- 1.3 tb_commission_record 佣金记录表新增字段
ALTER TABLE tb_commission_record
ADD COLUMN IF NOT EXISTS shop_id BIGINT,
ADD COLUMN IF NOT EXISTS balance_after BIGINT DEFAULT 0;

-- 添加索引
CREATE INDEX IF NOT EXISTS idx_commission_record_shop_id ON tb_commission_record(shop_id);

COMMENT ON COLUMN tb_commission_record.shop_id IS '店铺ID（佣金主要跟着店铺走）';
COMMENT ON COLUMN tb_commission_record.balance_after IS '入账后佣金余额（分）';

-- 1.4 tb_commission_withdrawal_setting 提现设置表新增字段
ALTER TABLE tb_commission_withdrawal_setting
ADD COLUMN IF NOT EXISTS daily_withdrawal_limit INT DEFAULT 3;

COMMENT ON COLUMN tb_commission_withdrawal_setting.daily_withdrawal_limit IS '每日提现次数限制';

-- 1.5 tb_iot_card 物联网卡表新增字段
ALTER TABLE tb_iot_card
ADD COLUMN IF NOT EXISTS shop_id BIGINT;

-- 添加索引
CREATE INDEX IF NOT EXISTS idx_iot_card_shop_id ON tb_iot_card(shop_id);

COMMENT ON COLUMN tb_iot_card.shop_id IS '店铺ID（冗余字段，方便查询）';

-- 1.6 tb_device 设备表新增字段
ALTER TABLE tb_device
ADD COLUMN IF NOT EXISTS shop_id BIGINT;

-- 添加索引
CREATE INDEX IF NOT EXISTS idx_device_shop_id ON tb_device(shop_id);

COMMENT ON COLUMN tb_device.shop_id IS '店铺ID（冗余字段，方便查询）';

-- ========================================
-- 2. 创建新表
-- ========================================

-- 2.1 tb_enterprise_card_authorization 企业卡授权表
CREATE TABLE IF NOT EXISTS tb_enterprise_card_authorization (
    id BIGSERIAL PRIMARY KEY,
    enterprise_id BIGINT NOT NULL,
    iot_card_id BIGINT NOT NULL,
    shop_id BIGINT NOT NULL,
    authorized_by BIGINT NOT NULL,
    authorized_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    status INT DEFAULT 1,
    creator BIGINT NOT NULL,
    updater BIGINT NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    deleted_at TIMESTAMP WITH TIME ZONE
);

-- 添加唯一约束（企业+卡唯一）
CREATE UNIQUE INDEX IF NOT EXISTS uk_enterprise_card 
ON tb_enterprise_card_authorization(enterprise_id, iot_card_id) WHERE deleted_at IS NULL;

-- 添加索引
CREATE INDEX IF NOT EXISTS idx_enterprise_card_auth_enterprise_id ON tb_enterprise_card_authorization(enterprise_id);
CREATE INDEX IF NOT EXISTS idx_enterprise_card_auth_iot_card_id ON tb_enterprise_card_authorization(iot_card_id);
CREATE INDEX IF NOT EXISTS idx_enterprise_card_auth_shop_id ON tb_enterprise_card_authorization(shop_id);
CREATE INDEX IF NOT EXISTS idx_enterprise_card_auth_status ON tb_enterprise_card_authorization(status);

-- 添加表注释
COMMENT ON TABLE tb_enterprise_card_authorization IS '企业卡授权表，记录企业被授权可见的卡';
COMMENT ON COLUMN tb_enterprise_card_authorization.enterprise_id IS '企业ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.iot_card_id IS 'IoT卡ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.shop_id IS '店铺ID（授权方）';
COMMENT ON COLUMN tb_enterprise_card_authorization.authorized_by IS '授权人ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.authorized_at IS '授权时间';
COMMENT ON COLUMN tb_enterprise_card_authorization.status IS '状态 1=有效 0=已回收';
COMMENT ON COLUMN tb_enterprise_card_authorization.creator IS '创建人ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.updater IS '更新人ID';

-- 2.2 tb_asset_allocation_record 资产分配记录表
CREATE TABLE IF NOT EXISTS tb_asset_allocation_record (
    id BIGSERIAL PRIMARY KEY,
    allocation_no VARCHAR(50) NOT NULL,
    allocation_type VARCHAR(20) NOT NULL,
    asset_type VARCHAR(20) NOT NULL,
    asset_id BIGINT NOT NULL,
    asset_identifier VARCHAR(50) NOT NULL,
    from_owner_type VARCHAR(20),
    from_owner_id BIGINT,
    to_owner_type VARCHAR(20) NOT NULL,
    to_owner_id BIGINT NOT NULL,
    related_device_id BIGINT,
    related_card_ids JSONB,
    operator_id BIGINT NOT NULL,
    remark TEXT,
    creator BIGINT NOT NULL,
    updater BIGINT NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    deleted_at TIMESTAMP WITH TIME ZONE
);

-- 添加唯一约束（分配单号唯一）
CREATE UNIQUE INDEX IF NOT EXISTS uk_asset_allocation_no 
ON tb_asset_allocation_record(allocation_no) WHERE deleted_at IS NULL;

-- 添加索引
CREATE INDEX IF NOT EXISTS idx_asset_allocation_type ON tb_asset_allocation_record(allocation_type);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_asset_type ON tb_asset_allocation_record(asset_type);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_asset_id ON tb_asset_allocation_record(asset_id);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_from_owner ON tb_asset_allocation_record(from_owner_type, from_owner_id);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_to_owner ON tb_asset_allocation_record(to_owner_type, to_owner_id);

-- 添加表注释
COMMENT ON TABLE tb_asset_allocation_record IS '资产分配记录表，记录卡/设备在平台和代理商之间的流转历史';
COMMENT ON COLUMN tb_asset_allocation_record.allocation_no IS '分配单号（唯一）';
COMMENT ON COLUMN tb_asset_allocation_record.allocation_type IS '分配类型 allocate=分配 recall=回收';
COMMENT ON COLUMN tb_asset_allocation_record.asset_type IS '资产类型 iot_card=物联网卡 device=设备';
COMMENT ON COLUMN tb_asset_allocation_record.asset_id IS '资产ID';
COMMENT ON COLUMN tb_asset_allocation_record.asset_identifier IS '资产标识符（ICCID或设备号）';
COMMENT ON COLUMN tb_asset_allocation_record.from_owner_type IS '来源所有者类型';
COMMENT ON COLUMN tb_asset_allocation_record.from_owner_id IS '来源所有者ID';
COMMENT ON COLUMN tb_asset_allocation_record.to_owner_type IS '目标所有者类型';
COMMENT ON COLUMN tb_asset_allocation_record.to_owner_id IS '目标所有者ID';
COMMENT ON COLUMN tb_asset_allocation_record.related_device_id IS '关联设备ID';
COMMENT ON COLUMN tb_asset_allocation_record.related_card_ids IS '关联卡ID列表';
COMMENT ON COLUMN tb_asset_allocation_record.operator_id IS '操作人ID';
COMMENT ON COLUMN tb_asset_allocation_record.remark IS '备注';
COMMENT ON COLUMN tb_asset_allocation_record.creator IS '创建人ID';
COMMENT ON COLUMN tb_asset_allocation_record.updater IS '更新人ID';

-- ========================================
-- 3. 数据迁移 - owner_type 枚举统一
-- ========================================

-- 3.1 更新 tb_iot_card 表 owner_type='agent' 为 'shop'
UPDATE tb_iot_card SET owner_type = 'shop' WHERE owner_type = 'agent';

-- 3.2 更新 tb_device 表 owner_type='agent' 为 'shop'
UPDATE tb_device SET owner_type = 'shop' WHERE owner_type = 'agent';

-- 3.3 填充 tb_iot_card.shop_id 字段（owner_type='shop' 时等于 owner_id）
UPDATE tb_iot_card SET shop_id = owner_id WHERE owner_type = 'shop' AND shop_id IS NULL;

-- 3.4 填充 tb_device.shop_id 字段（owner_type='shop' 时等于 owner_id）
UPDATE tb_device SET shop_id = owner_id WHERE owner_type = 'shop' AND shop_id IS NULL;
