-- 优惠券状态管理优化SQL脚本
-- 作者: WebSoft
-- 日期: 2025-01-15
-- 说明: 优化优惠券查询性能，添加必要的索引

-- ========================================
-- 1. 添加索引优化查询性能
-- ========================================

-- 用户优惠券表索引优化
CREATE INDEX IF NOT EXISTS idx_user_coupon_status ON shop_user_coupon(user_id, status, expire_time);
CREATE INDEX IF NOT EXISTS idx_user_coupon_expire ON shop_user_coupon(expire_time) WHERE status = 0;
CREATE INDEX IF NOT EXISTS idx_user_coupon_order ON shop_user_coupon(order_id) WHERE status = 1;

-- 优惠券模板表索引优化  
CREATE INDEX IF NOT EXISTS idx_coupon_status_expire ON shop_coupon(status, expire_type, end_time);

-- ========================================
-- 2. 统一状态字段（如果需要数据迁移）
-- ========================================

-- 检查现有数据的状态一致性
SELECT 
    '状态一致性检查' as check_item,
    COUNT(*) as total_count,
    SUM(CASE WHEN status = 0 AND is_use = 0 AND is_expire = 0 THEN 1 ELSE 0 END) as available_count,
    SUM(CASE WHEN status = 1 AND is_use = 1 THEN 1 ELSE 0 END) as used_count,
    SUM(CASE WHEN status = 2 OR is_expire = 1 THEN 1 ELSE 0 END) as expired_count,
    SUM(CASE WHEN 
        (status = 0 AND (is_use = 1 OR is_expire = 1)) OR
        (status = 1 AND is_use = 0) OR
        (status = 2 AND is_expire = 0)
        THEN 1 ELSE 0 END) as inconsistent_count
FROM shop_user_coupon;

-- 修复状态不一致的数据
UPDATE shop_user_coupon 
SET status = 1, is_use = 1 
WHERE status = 0 AND is_use = 1 AND is_expire = 0;

UPDATE shop_user_coupon 
SET status = 2, is_expire = 1 
WHERE status = 0 AND is_expire = 1;

UPDATE shop_user_coupon 
SET status = 2, is_expire = 1 
WHERE status IN (0, 1) AND end_time < NOW();

-- ========================================
-- 3. 添加触发器自动更新过期状态（可选）
-- ========================================

DELIMITER $$

-- 创建触发器：在查询时自动检查过期状态
CREATE TRIGGER IF NOT EXISTS tr_check_coupon_expire 
BEFORE UPDATE ON shop_user_coupon
FOR EACH ROW
BEGIN
    -- 如果是未使用状态且已过期，自动更新为过期状态
    IF NEW.status = 0 AND NEW.end_time < NOW() THEN
        SET NEW.status = 2;
        SET NEW.is_expire = 1;
    END IF;
END$$

DELIMITER ;

-- ========================================
-- 4. 创建视图简化查询
-- ========================================

-- 创建用户可用优惠券视图
CREATE OR REPLACE VIEW v_user_available_coupons AS
SELECT 
    uc.*,
    c.name as coupon_name,
    c.description as coupon_description,
    c.apply_range,
    c.apply_range_config,
    CASE 
        WHEN uc.end_time < NOW() THEN '已过期'
        WHEN uc.status = 1 THEN '已使用'
        WHEN uc.status = 0 THEN '可使用'
        ELSE '未知状态'
    END as status_desc
FROM shop_user_coupon uc
LEFT JOIN shop_coupon c ON uc.coupon_id = c.id
WHERE uc.deleted = 0;

-- 创建优惠券统计视图
CREATE OR REPLACE VIEW v_coupon_statistics AS
SELECT 
    user_id,
    COUNT(*) as total_count,
    SUM(CASE WHEN status = 0 AND end_time >= NOW() THEN 1 ELSE 0 END) as available_count,
    SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count,
    SUM(CASE WHEN status = 2 OR end_time < NOW() THEN 1 ELSE 0 END) as expired_count
FROM shop_user_coupon 
WHERE deleted = 0
GROUP BY user_id;

-- ========================================
-- 5. 存储过程：批量处理过期优惠券
-- ========================================

DELIMITER $$

CREATE PROCEDURE IF NOT EXISTS sp_update_expired_coupons()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE update_count INT DEFAULT 0;
    
    -- 声明异常处理
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
    BEGIN
        ROLLBACK;
        RESIGNAL;
    END;
    
    START TRANSACTION;
    
    -- 批量更新过期优惠券
    UPDATE shop_user_coupon 
    SET status = 2, is_expire = 1
    WHERE status = 0 
      AND end_time < NOW() 
      AND deleted = 0;
    
    -- 获取更新数量
    SET update_count = ROW_COUNT();
    
    COMMIT;
    
    -- 返回更新数量
    SELECT update_count as updated_count;
    
END$$

DELIMITER ;

-- ========================================
-- 6. 性能监控查询
-- ========================================

-- 查看优惠券状态分布
SELECT 
    status,
    CASE 
        WHEN status = 0 THEN '未使用'
        WHEN status = 1 THEN '已使用'  
        WHEN status = 2 THEN '已过期'
        ELSE '未知'
    END as status_name,
    COUNT(*) as count,
    ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM shop_user_coupon WHERE deleted = 0), 2) as percentage
FROM shop_user_coupon 
WHERE deleted = 0
GROUP BY status
ORDER BY status;

-- 查看即将过期的优惠券（7天内）
SELECT 
    COUNT(*) as expiring_soon_count,
    MIN(end_time) as earliest_expire_time,
    MAX(end_time) as latest_expire_time
FROM shop_user_coupon 
WHERE status = 0 
  AND end_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY)
  AND deleted = 0;

-- 查看优惠券使用率统计
SELECT 
    DATE(create_time) as date,
    COUNT(*) as issued_count,
    SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count,
    ROUND(SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as usage_rate
FROM shop_user_coupon 
WHERE deleted = 0
  AND create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(create_time)
ORDER BY date DESC;

-- ========================================
-- 7. 清理和维护
-- ========================================

-- 清理过期很久的优惠券记录（可选，谨慎使用）
-- DELETE FROM shop_user_coupon 
-- WHERE status = 2 
--   AND end_time < DATE_SUB(NOW(), INTERVAL 1 YEAR)
--   AND deleted = 0;

COMMIT;
