package com.ycwl.basic.pricing.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ycwl.basic.pricing.entity.PriceCouponClaimRecord;
import com.ycwl.basic.pricing.enums.CouponStatus;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * 优惠券领用记录Mapper
 */
@Mapper
public interface PriceCouponClaimRecordMapper extends BaseMapper<PriceCouponClaimRecord> {
    
    /**
     * 查询用户可用的优惠券记录
     */
    @Select("SELECT r.*, c.coupon_name, c.coupon_type, c.discount_value, c.min_amount, " +
            "c.max_discount, c.applicable_products, c.valid_from, c.valid_until " +
            "FROM price_coupon_claim_record r " +
            "JOIN price_coupon_config c ON r.coupon_id = c.id " +
            "WHERE r.user_id = #{userId} AND r.status = 'CLAIMED' " +
            "AND c.is_active = 1 AND c.valid_from <= NOW() AND c.valid_until > NOW() " +
            "AND (r.expire_time IS NULL OR r.expire_time > NOW())")
    List<PriceCouponClaimRecord> selectUserAvailableCoupons(Long userId);
    
    /**
     * 查询用户特定优惠券记录（检查是否领取过，不限状态）
     */
    @Select("SELECT * FROM price_coupon_claim_record " +
            "WHERE user_id = #{userId} AND coupon_id = #{couponId}")
    List<PriceCouponClaimRecord> selectUserCouponRecords(@Param("userId") Long userId,
                                                  @Param("couponId") Long couponId);

    /**
     * 统计用户领取某优惠券的次数（所有状态）
     */
    @Select("SELECT COUNT(*) FROM price_coupon_claim_record " +
            "WHERE user_id = #{userId} AND coupon_id = #{couponId} AND deleted = 0 FOR UPDATE")
    int countUserCouponClaims(@Param("userId") Long userId, @Param("couponId") Long couponId);

    /**
     * 更新优惠券使用状态
     */
    @Update("UPDATE price_coupon_claim_record SET status = #{status}, " +
            "use_time = #{useTime}, order_id = #{orderId}, scenic_id = #{scenicId}, update_time = NOW() " +
            "WHERE id = #{id}")
    int updateCouponStatus(@Param("id") Long id, 
                          @Param("status") CouponStatus status,
                          @Param("useTime") java.util.Date useTime,
                          @Param("orderId") String orderId,
                          @Param("scenicId") String scenicId);
    
    /**
     * 插入优惠券领用记录
     */
    @Insert("INSERT INTO price_coupon_claim_record (coupon_id, user_id, claim_time, expire_time, status, scenic_id, create_time, update_time) " +
            "VALUES (#{couponId}, #{userId}, NOW(), #{expireTime}, #{status}, #{scenicId}, NOW(), NOW())")
    int insertClaimRecord(PriceCouponClaimRecord record);
    
    /**
     * 更新优惠券记录
     */
    @Update("UPDATE price_coupon_claim_record SET status = #{status}, use_time = #{useTime}, " +
            "order_id = #{orderId}, update_time = NOW() WHERE id = #{id}")
    int updateClaimRecord(PriceCouponClaimRecord record);
    
    // ==================== 管理端接口 ====================
    
    /**
     * 管理端：查询所有优惠券领取记录（支持分页）
     */
    @Select("SELECT r.*, c.coupon_name, c.coupon_type, c.discount_value " +
            "FROM price_coupon_claim_record r " +
            "LEFT JOIN price_coupon_config c ON r.coupon_id = c.id " +
            "ORDER BY r.create_time DESC")
    List<PriceCouponClaimRecord> selectAllForAdmin();
    
    /**
     * 管理端：根据条件查询优惠券领取记录（支持分页）
     */
    @Select("<script>" +
            "SELECT r.*, c.coupon_name, c.coupon_type, c.discount_value " +
            "FROM price_coupon_claim_record r " +
            "LEFT JOIN price_coupon_config c ON r.coupon_id = c.id " +
            "<where>" +
            "<if test='userId != null'>" +
            "AND r.user_id = #{userId} " +
            "</if>" +
            "<if test='couponId != null'>" +
            "AND r.coupon_id = #{couponId} " +
            "</if>" +
            "<if test='status != null'>" +
            "AND r.status = #{status} " +
            "</if>" +
            "<if test='startTime != null and startTime != \"\"'>" +
            "AND r.claim_time >= #{startTime} " +
            "</if>" +
            "<if test='endTime != null and endTime != \"\"'>" +
            "AND r.claim_time &lt;= #{endTime} " +
            "</if>" +
            "<if test='scenicId != null and scenicId != \"\"'>" +
            "AND r.scenic_id = #{scenicId} " +
            "</if>" +
            "</where>" +
            "ORDER BY r.create_time DESC" +
            "</script>")
    List<PriceCouponClaimRecord> selectByConditionsForAdmin(@Param("userId") Long userId, 
                                                           @Param("couponId") Long couponId, 
                                                           @Param("status") CouponStatus status,
                                                           @Param("startTime") String startTime,
                                                           @Param("endTime") String endTime,
                                                           @Param("scenicId") String scenicId);
    
    /**
     * 管理端：根据用户ID查询优惠券领取记录
     */
    @Select("SELECT r.*, c.coupon_name, c.coupon_type, c.discount_value " +
            "FROM price_coupon_claim_record r " +
            "LEFT JOIN price_coupon_config c ON r.coupon_id = c.id " +
            "WHERE r.user_id = #{userId} " +
            "ORDER BY r.create_time DESC")
    List<PriceCouponClaimRecord> selectByUserIdForAdmin(@Param("userId") Long userId);
    
    /**
     * 管理端：根据优惠券ID查询领取记录
     */
    @Select("SELECT r.*, c.coupon_name, c.coupon_type, c.discount_value " +
            "FROM price_coupon_claim_record r " +
            "LEFT JOIN price_coupon_config c ON r.coupon_id = c.id " +
            "WHERE r.coupon_id = #{couponId} " +
            "ORDER BY r.create_time DESC")
    List<PriceCouponClaimRecord> selectByCouponIdForAdmin(@Param("couponId") Long couponId);
    
    /**
     * 管理端：根据状态查询领取记录
     */
    @Select("SELECT r.*, c.coupon_name, c.coupon_type, c.discount_value " +
            "FROM price_coupon_claim_record r " +
            "LEFT JOIN price_coupon_config c ON r.coupon_id = c.id " +
            "WHERE r.status = #{status} " +
            "ORDER BY r.create_time DESC")
    List<PriceCouponClaimRecord> selectByStatusForAdmin(@Param("status") CouponStatus status);
    
    /**
     * 管理端：统计优惠券使用情况
     */
    @Select("SELECT " +
            "COUNT(*) as total_claimed, " +
            "COUNT(CASE WHEN status = 'USED' THEN 1 END) as total_used, " +
            "COUNT(CASE WHEN status = 'CLAIMED' THEN 1 END) as total_available " +
            "FROM price_coupon_claim_record WHERE coupon_id = #{couponId}")
    java.util.Map<String, Object> selectCouponUsageStats(@Param("couponId") Long couponId);
    
    /**
     * 管理端：统计优惠券详细使用情况
     */
    @Select("SELECT " +
            "COUNT(*) as total_claimed, " +
            "COUNT(CASE WHEN status = 'USED' THEN 1 END) as total_used, " +
            "COUNT(CASE WHEN status = 'CLAIMED' THEN 1 END) as total_available, " +
            "CASE WHEN COUNT(*) > 0 THEN COUNT(CASE WHEN status = 'USED' THEN 1 END) / COUNT(*) ELSE 0 END as usage_rate, " +
            "CASE WHEN COUNT(CASE WHEN status = 'USED' THEN 1 END) > 0 THEN " +
            "AVG(CASE WHEN status = 'USED' AND use_time IS NOT NULL AND claim_time IS NOT NULL THEN " +
            "DATEDIFF(use_time, claim_time) END) ELSE 0 END as avg_days_to_use " +
            "FROM price_coupon_claim_record WHERE coupon_id = #{couponId}")
    java.util.Map<String, Object> selectCouponDetailStats(@Param("couponId") Long couponId);
    
    /**
     * 管理端：统计时间范围内的数据
     */
    @Select("<script>" +
            "SELECT " +
            "COUNT(*) as total_claimed, " +
            "COUNT(CASE WHEN status = 'USED' THEN 1 END) as total_used, " +
            "COUNT(CASE WHEN status = 'CLAIMED' THEN 1 END) as total_available, " +
            "COUNT(CASE WHEN status = 'EXPIRED' THEN 1 END) as total_expired, " +
            "COUNT(DISTINCT coupon_id) as total_coupon_types, " +
            "COUNT(DISTINCT user_id) as total_users " +
            "FROM price_coupon_claim_record " +
            "WHERE claim_time >= #{startDate} AND claim_time &lt;= #{endDate} " +
            "<if test='scenicId != null and scenicId != \"\"'>" +
            "AND scenic_id = #{scenicId} " +
            "</if>" +
            "</script>")
    java.util.Map<String, Object> selectPeriodStats(@Param("startDate") String startDate, 
                                                    @Param("endDate") String endDate,
                                                    @Param("scenicId") String scenicId);
    
    /**
     * 根据景区ID查询优惠券领取记录
     */
    @Select("SELECT r.*, c.coupon_name, c.coupon_type, c.discount_value " +
            "FROM price_coupon_claim_record r " +
            "LEFT JOIN price_coupon_config c ON r.coupon_id = c.id " +
            "WHERE r.scenic_id = #{scenicId} " +
            "ORDER BY r.create_time DESC")
    List<PriceCouponClaimRecord> selectByScenicIdForAdmin(@Param("scenicId") String scenicId);
    
    /**
     * 统计景区优惠券使用情况
     */
    @Select("SELECT " +
            "COUNT(*) as total_claimed, " +
            "COUNT(CASE WHEN status = 'USED' THEN 1 END) as total_used, " +
            "COUNT(CASE WHEN status = 'CLAIMED' THEN 1 END) as total_available, " +
            "COUNT(CASE WHEN status = 'EXPIRED' THEN 1 END) as total_expired, " +
            "COUNT(DISTINCT coupon_id) as total_coupon_types, " +
            "COUNT(DISTINCT user_id) as total_users " +
            "FROM price_coupon_claim_record WHERE scenic_id = #{scenicId}")
    java.util.Map<String, Object> selectScenicCouponUsageStats(@Param("scenicId") String scenicId);
}
