package com.ycwl.basic.pricing.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ycwl.basic.pricing.entity.PriceVoucherCode;
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.time.LocalDateTime;
import java.util.List;

/**
 * 券码Mapper
 */
@Mapper
public interface PriceVoucherCodeMapper extends BaseMapper<PriceVoucherCode> {

    /**
     * 根据券码查询券码信息
     * @param code 券码
     * @return 券码信息
     */
    @Select("SELECT id, batch_id, scenic_id, code, status, user_id, claimed_time, used_time, " +
            "current_use_count, last_used_time, remark, create_time, update_time, deleted, deleted_at " +
            "FROM price_voucher_code WHERE code = #{code} AND deleted = 0 LIMIT 1")
    PriceVoucherCode selectByCode(@Param("code") String code);

    /**
     * 根据userId和scenicId统计已领取的券码数量
     * @param userId 用户ID
     * @param scenicId 景区ID
     * @return 数量
     */
    @Select("SELECT COUNT(1) FROM price_voucher_code WHERE user_id = #{userId} AND scenic_id = #{scenicId} AND deleted = 0")
    Integer countByUserIdAndScenicId(@Param("userId") Long userId, @Param("scenicId") Long scenicId);

    /**
     * 查询用户在指定景区的可用券码列表
     * @param userId 用户ID
     * @param scenicId 景区ID
     * @return 券码列表
     */
    @Select("SELECT id, batch_id, scenic_id, code, status, user_id, claimed_time, used_time, " +
            "current_use_count, last_used_time, remark, create_time, update_time, deleted, deleted_at " +
            "FROM price_voucher_code WHERE user_id = #{userId} AND scenic_id = #{scenicId} AND status = 1 AND deleted = 0 " +
            "ORDER BY claimed_time DESC")
    List<PriceVoucherCode> selectAvailableVouchersByUserIdAndScenicId(@Param("userId") Long userId,
                                                                      @Param("scenicId") Long scenicId);

    /**
     * 根据批次ID获取可领取的券码（未领取状态）
     * @param batchId 批次ID
     * @param limit 限制数量
     * @return 券码列表
     */
    @Select("SELECT id, batch_id, scenic_id, code, status, user_id, claimed_time, used_time, " +
            "current_use_count, last_used_time, remark, create_time, update_time, deleted, deleted_at " +
            "FROM price_voucher_code WHERE batch_id = #{batchId} AND status = 0 AND deleted = 0 LIMIT #{limit}")
    List<PriceVoucherCode> selectUnclaimedVouchersByBatchId(@Param("batchId") Long batchId,
                                                            @Param("limit") Integer limit);

    /**
     * 领取券码（更新状态为已领取）
     * @param id 券码ID
     * @param userId 用户ID
     * @param claimedTime 领取时间
     * @return 影响行数
     */
    @Update("UPDATE price_voucher_code SET status = 1, user_id = #{userId}, claimed_time = #{claimedTime}, " +
            "update_time = NOW() WHERE id = #{id} AND status = 0 AND deleted = 0")
    int claimVoucher(@Param("id") Long id,
                     @Param("userId") Long userId,
                     @Param("claimedTime") LocalDateTime claimedTime);

    /**
     * 根据批次ID查询券码列表（支持分页）
     * @param batchId 批次ID
     * @return 券码列表
     */
    @Select("SELECT id, batch_id, scenic_id, code, status, user_id, claimed_time, used_time, " +
            "current_use_count, last_used_time, remark, create_time, update_time, deleted, deleted_at " +
            "FROM price_voucher_code WHERE batch_id = #{batchId} AND deleted = 0 ORDER BY create_time DESC")
    List<PriceVoucherCode> selectByBatchId(@Param("batchId") Long batchId);

    /**
     * 查询用户的券码列表
     * @param userId 用户ID
     * @param scenicId 景区ID（可选）
     * @return 券码列表
     */
    @Select("<script>" +
            "SELECT id, batch_id, scenic_id, code, status, user_id, claimed_time, used_time, " +
            "current_use_count, last_used_time, remark, create_time, update_time, deleted, deleted_at " +
            "FROM price_voucher_code WHERE user_id = #{userId}" +
            "<if test='scenicId != null'> AND scenic_id = #{scenicId}</if>" +
            " AND deleted = 0 ORDER BY claimed_time DESC" +
            "</script>")
    List<PriceVoucherCode> selectUserVouchers(@Param("userId") Long userId,
                                              @Param("scenicId") Long scenicId);

    /**
     * 根据批次ID查询第一个可用的券码
     * @param batchId 批次ID
     * @return 可用券码
     */
    @Select("SELECT id, batch_id, scenic_id, code, status, user_id, claimed_time, used_time, " +
            "current_use_count, last_used_time, remark, create_time, update_time, deleted, deleted_at " +
            "FROM price_voucher_code WHERE batch_id = #{batchId} AND status = 0 AND deleted = 0 LIMIT 1")
    PriceVoucherCode findFirstAvailableByBatchId(@Param("batchId") Long batchId);

    /**
     * 随机获取一个未被打印过的可用券码
     * @param scenicId 景区ID
     * @return 可用券码
     */
    @Select("SELECT pvc.id, pvc.batch_id, pvc.scenic_id, pvc.code, pvc.status, pvc.user_id, pvc.claimed_time, pvc.used_time, " +
            "pvc.current_use_count, pvc.last_used_time, pvc.remark, pvc.create_time, pvc.update_time, pvc.deleted, pvc.deleted_at " +
            "FROM price_voucher_code pvc WHERE pvc.scenic_id = #{scenicId} AND pvc.status = 0 AND pvc.deleted = 0 " +
            "AND NOT EXISTS (SELECT 1 FROM voucher_print_record vpr WHERE vpr.voucher_code_id = pvc.id AND vpr.deleted = 0) " +
            "ORDER BY RAND() LIMIT 1")
    PriceVoucherCode findRandomUnprintedVoucher(@Param("scenicId") Long scenicId);
}
