-- ============================================
-- 1. member_user 表（会员表）
-- ============================================

-- Step 1: 删除已存在的表（如果需要重建）
-- DROP TABLE IF EXISTS member_user CASCADE;

-- Step 2: 创建 member_user 表
CREATE TABLE IF NOT EXISTS member_user (
    -- ========== 主键和基础字段（来自BaseEntity）==========
    id BIGSERIAL PRIMARY KEY,                                      -- 主键ID，自增
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,      -- 创建时间
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,      -- 更新时间
    
    -- ========== 会员核心字段 ==========
    member_no VARCHAR(50) NOT NULL UNIQUE,                         -- 会员编号（唯一）
    nickname VARCHAR(100),                                         -- 昵称
    phone VARCHAR(255),                                            -- 手机号（AES加密存储）
    gender INTEGER DEFAULT 0,                                      -- 性别：0-未知，1-男，2-女
    birthday DATE,                                            -- 生日
    address VARCHAR(500),                                          -- 地址
    avatar VARCHAR(500),                                           -- 头像URL
    subscribed BOOLEAN DEFAULT FALSE,                              -- 是否关注服务号
    last_login_at TIMESTAMP,                                       -- 最后登录时间
    
    -- ========== 微信相关字段 ==========
    union_id VARCHAR(100),                                         -- 微信UnionID（跨应用唯一标识）
    miniapp_open_id VARCHAR(100),                                  -- 小程序OpenID
    official_open_id VARCHAR(100),                                 -- 服务号OpenID
    
    -- ========== 软删除字段 ==========
    is_deleted BOOLEAN DEFAULT FALSE                               -- 是否删除（软删除标记）
);

-- Step 3: 创建索引
-- 会员编号索引（唯一索引，加速查询）
CREATE UNIQUE INDEX IF NOT EXISTS idx_member_user_member_no ON member_user(member_no);

-- UnionID索引（加速跨平台用户查找）
CREATE INDEX IF NOT EXISTS idx_member_user_union_id ON member_user(union_id);

-- 小程序OpenID索引（加速小程序登录查询）
CREATE INDEX IF NOT EXISTS idx_member_user_miniapp_openid ON member_user(miniapp_open_id);

-- 服务号OpenID索引（加速服务号事件处理）
CREATE INDEX IF NOT EXISTS idx_member_user_official_openid ON member_user(official_open_id);

-- 手机号索引（加速手机号查询和去重）
CREATE INDEX IF NOT EXISTS idx_member_user_phone ON member_user(phone);

-- 软删除索引（加速查询未删除的记录）
CREATE INDEX IF NOT EXISTS idx_member_user_is_deleted ON member_user(is_deleted);

-- Step 4: 添加注释
COMMENT ON TABLE member_user IS '会员表';

COMMENT ON COLUMN member_user.id IS '主键ID';
COMMENT ON COLUMN member_user.created_at IS '创建时间';
COMMENT ON COLUMN member_user.updated_at IS '更新时间';

COMMENT ON COLUMN member_user.member_no IS '会员编号（唯一，格式：MEM + 8位随机字符）';
COMMENT ON COLUMN member_user.nickname IS '昵称';
COMMENT ON COLUMN member_user.phone IS '手机号（AES-128-CBC加密存储）';
COMMENT ON COLUMN member_user.gender IS '性别：0-未知，1-男，2-女';
COMMENT ON COLUMN member_user.birthday IS '生日';
COMMENT ON COLUMN member_user.address IS '地址';
COMMENT ON COLUMN member_user.avatar IS '头像URL';
COMMENT ON COLUMN member_user.subscribed IS '是否关注服务号：true-已关注，false-未关注';
COMMENT ON COLUMN member_user.last_login_at IS '最后登录时间';

COMMENT ON COLUMN member_user.union_id IS '微信UnionID（用户在开放平台的唯一标识，跨应用相同）';
COMMENT ON COLUMN member_user.miniapp_open_id IS '小程序OpenID（用户在当前小程序的唯一标识）';
COMMENT ON COLUMN member_user.official_open_id IS '服务号OpenID（用户在当前服务号的唯一标识）';

COMMENT ON COLUMN member_user.is_deleted IS '是否删除（软删除标记）：false-正常，true-已删除';


-- ============================================
-- 2. wechat_user 表（微信用户表）
-- ============================================

-- Step 1: 删除已存在的表（如果需要重建）
-- DROP TABLE IF EXISTS wechat_user CASCADE;

-- Step 2: 创建 wechat_user 表
CREATE TABLE IF NOT EXISTS wechat_user (
    -- ========== 主键和基础字段（来自BaseEntity）==========
    id BIGSERIAL PRIMARY KEY,                                      -- 主键ID，自增
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,      -- 创建时间
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,      -- 更新时间
    
    -- ========== 关联字段 ==========
    member_id BIGINT NOT NULL,                                     -- 会员ID（外键）
    
    -- ========== 微信标识字段 ==========
    union_id VARCHAR(100),                                         -- 微信UnionID
    miniapp_openid VARCHAR(100),                                   -- 小程序OpenID
    mp_openid VARCHAR(100),                                        -- 服务号OpenID
    
    -- ========== 关注状态字段 ==========
    is_subscribed BOOLEAN DEFAULT FALSE,                           -- 是否关注服务号
    subscribe_time TIMESTAMP,                                      -- 首次关注时间
    unsubscribe_time TIMESTAMP                                     -- 最后一次取消关注时间
);

-- Step 3: 创建外键约束
ALTER TABLE wechat_user 
    ADD CONSTRAINT fk_wechat_user_member 
    FOREIGN KEY (member_id) REFERENCES member_user(id) ON DELETE CASCADE;

-- Step 4: 创建索引
-- UnionID索引（加速跨平台用户查找）
CREATE INDEX IF NOT EXISTS idx_wechat_user_union_id ON wechat_user(union_id);

-- 小程序OpenID索引（加速小程序登录查询）
CREATE INDEX IF NOT EXISTS idx_wechat_user_miniapp_openid ON wechat_user(miniapp_openid);

-- 服务号OpenID索引（加速服务号事件处理）
CREATE INDEX IF NOT EXISTS idx_wechat_user_mp_openid ON wechat_user(mp_openid);

-- 会员ID索引（加速关联查询）
CREATE INDEX IF NOT EXISTS idx_wechat_user_member_id ON wechat_user(member_id);

-- Step 5: 添加注释
COMMENT ON TABLE wechat_user IS '微信用户表';

COMMENT ON COLUMN wechat_user.id IS '主键ID';
COMMENT ON COLUMN wechat_user.created_at IS '创建时间';
COMMENT ON COLUMN wechat_user.updated_at IS '更新时间';

COMMENT ON COLUMN wechat_user.member_id IS '会员ID（关联 member_user 表的 id 字段）';
COMMENT ON COLUMN wechat_user.union_id IS '微信UnionID（用户在开放平台的唯一标识）';
COMMENT ON COLUMN wechat_user.miniapp_openid IS '小程序OpenID（用户在当前小程序的唯一标识）';
COMMENT ON COLUMN wechat_user.mp_openid IS '服务号OpenID（用户在当前服务号的唯一标识）';

COMMENT ON COLUMN wechat_user.is_subscribed IS '是否关注服务号：true-已关注，false-未关注';
COMMENT ON COLUMN wechat_user.subscribe_time IS '首次关注时间';
COMMENT ON COLUMN wechat_user.unsubscribe_time IS '最后一次取消关注时间';


-- ============================================
-- 3. member_card 表（会员卡类型表）
-- ============================================
CREATE TABLE IF NOT EXISTS member_card (
    id BIGSERIAL PRIMARY KEY,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP,
    
    member_card_id BIGSERIAL,
    member_card_name VARCHAR(100) NOT NULL,
    member_card_type VARCHAR(20) NOT NULL,
    member_card_price DECIMAL(10, 2) NOT NULL,
    member_card_validity_days INTEGER,
    member_card_total_times INTEGER,
    member_card_amount DECIMAL(10, 2),
    member_card_status INTEGER DEFAULT 1 NOT NULL,
    extra_config TEXT DEFAULT '{}'
);

COMMENT ON TABLE member_card IS '会员卡类型表';
COMMENT ON COLUMN member_card.member_card_id IS '会员卡ID';
COMMENT ON COLUMN member_card.member_card_name IS '会员卡名称';
COMMENT ON COLUMN member_card.member_card_type IS '会员卡类型：TIME_CARD-时长卡, COUNT_CARD-次卡, STORED_VALUE_CARD-储值卡';
COMMENT ON COLUMN member_card.member_card_price IS '会员卡价格';
COMMENT ON COLUMN member_card.member_card_validity_days IS '有效天数（时长卡用）';
COMMENT ON COLUMN member_card.member_card_total_times IS '总次数（次卡用）';
COMMENT ON COLUMN member_card.member_card_amount IS '面额（储值卡用）';
COMMENT ON COLUMN member_card.member_card_status IS '状态：0-下架, 1-上架';
COMMENT ON COLUMN member_card.extra_config IS '扩展配置（JSON格式）';


-- ============================================
-- 4. member_card_record 表（会员卡记录表）
-- ============================================
CREATE TABLE IF NOT EXISTS member_card_record (
    id BIGSERIAL PRIMARY KEY,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP,
    
    member_card_record_id BIGSERIAL,
    member_id BIGINT NOT NULL,
    member_card_id BIGINT NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
    remaining_times INTEGER DEFAULT 0,
    remaining_amount DECIMAL(10, 2) DEFAULT 0.00,
    expire_time TIMESTAMP,
    source_order_id BIGINT,
    purchase_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    version INTEGER DEFAULT 0 NOT NULL,
    card_composition TEXT
);

-- 索引优化
CREATE INDEX IF NOT EXISTS idx_member_card_record_member_id ON member_card_record(member_id);
CREATE INDEX IF NOT EXISTS idx_member_card_record_status ON member_card_record(status);
CREATE INDEX IF NOT EXISTS idx_member_card_record_expire_time ON member_card_record(expire_time);
CREATE INDEX IF NOT EXISTS idx_member_card_record_member_status ON member_card_record(member_id, status);
CREATE INDEX IF NOT EXISTS idx_member_card_record_status_expire ON member_card_record(status, expire_time)
    WHERE status = 'ACTIVE';

COMMENT ON TABLE member_card_record IS '会员卡记录表（会员持有的卡）';
COMMENT ON COLUMN member_card_record.member_card_record_id IS '会员卡记录ID';
COMMENT ON COLUMN member_card_record.member_id IS '会员ID';
COMMENT ON COLUMN member_card_record.member_card_id IS '会员卡类型ID';
COMMENT ON COLUMN member_card_record.status IS '状态：ACTIVE-有效, USED_UP-用完, EXPIRED-过期, REFUNDED-已退款';
COMMENT ON COLUMN member_card_record.remaining_times IS '剩余次数';
COMMENT ON COLUMN member_card_record.remaining_amount IS '剩余金额';
COMMENT ON COLUMN member_card_record.expire_time IS '到期时间';
COMMENT ON COLUMN member_card_record.source_order_id IS '来源订单ID';
COMMENT ON COLUMN member_card_record.purchase_time IS '购买时间';
COMMENT ON COLUMN member_card_record.version IS '乐观锁版本号';
COMMENT ON COLUMN member_card_record.card_composition IS '卡片组成（JSON格式，用于组合卡）';


-- ============================================
-- 5. member_card_transactions 表（会员卡交易流水表）
-- ============================================
CREATE TABLE IF NOT EXISTS member_card_transactions (
    id BIGSERIAL PRIMARY KEY,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    
    member_card_record_id BIGINT NOT NULL,
    member_id BIGINT NOT NULL,
    member_card_id BIGINT NOT NULL,
    operation_type VARCHAR(20) NOT NULL,
    change_amount INTEGER DEFAULT 0,
    change_balance DECIMAL(10, 2) DEFAULT 0.00,
    after_remaining_count INTEGER DEFAULT 0,
    after_remaining_balance DECIMAL(10, 2) DEFAULT 0.00,
    related_biz_type VARCHAR(20),
    source_order_id BIGINT,
    remark VARCHAR(500),
    is_archived BOOLEAN DEFAULT FALSE,
    archived_at TIMESTAMP
);

-- 索引优化
CREATE INDEX IF NOT EXISTS idx_member_card_transactions_member_id ON member_card_transactions(member_id);
CREATE INDEX IF NOT EXISTS idx_member_card_transactions_record_id ON member_card_transactions(member_card_record_id);
CREATE INDEX IF NOT EXISTS idx_member_card_transactions_created_at ON member_card_transactions(created_at);
CREATE INDEX IF NOT EXISTS idx_member_card_transactions_member_type_time
    ON member_card_transactions(member_id, operation_type, created_at);

COMMENT ON TABLE member_card_transactions IS '会员卡交易流水表';
COMMENT ON COLUMN member_card_transactions.operation_type IS '操作类型：PURCHASE-购买, DEDUCT-扣次/扣费, RENEW-续费, REFUND-退款, EXPIRE-过期';
COMMENT ON COLUMN member_card_transactions.change_amount IS '变动次数';
COMMENT ON COLUMN member_card_transactions.change_balance IS '变动金额';
COMMENT ON COLUMN member_card_transactions.after_remaining_count IS '变动后剩余次数';
COMMENT ON COLUMN member_card_transactions.after_remaining_balance IS '变动后剩余金额';
COMMENT ON COLUMN member_card_transactions.related_biz_type IS '关联业务类型：GROUP_CLASS-团课, PT_CLASS-私教, CHECK_IN-签到';
COMMENT ON COLUMN member_card_transactions.is_archived IS '是否已归档';
COMMENT ON COLUMN member_card_transactions.archived_at IS '归档时间';


-- ============================================
-- 6. refund_application 表（退款申请表）
-- ============================================
CREATE TABLE IF NOT EXISTS refund_application (
    id BIGSERIAL PRIMARY KEY,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP,
    
    record_id BIGINT NOT NULL,
    member_id BIGINT NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
    reason VARCHAR(500),
    apply_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    audit_time TIMESTAMP,
    auditor_id BIGINT,
    audit_remark VARCHAR(500),
    refund_amount DECIMAL(10, 2)
);

CREATE INDEX IF NOT EXISTS idx_refund_application_record_id ON refund_application(record_id);
CREATE INDEX IF NOT EXISTS idx_refund_application_status ON refund_application(status);

COMMENT ON TABLE refund_application IS '退款申请表';
COMMENT ON COLUMN refund_application.status IS '状态：PENDING-待审核, APPROVED-已批准, REJECTED-已拒绝, PROCESSING-处理中, SUCCESS-成功, FAILED-失败';
