package com.gxwebsoft.glt.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.glt.entity.GltUserTicket;
import com.gxwebsoft.glt.param.GltUserTicketParam;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 我的水票Mapper
 *
 * @author 科技小王子
 * @since 2026-02-03 18:55:55
 */
public interface GltUserTicketMapper extends BaseMapper<GltUserTicket> {

    /**
     * 分页查询
     *
     * @param page  分页对象
     * @param param 查询参数
     * @return List<GltUserTicket>
     */
    List<GltUserTicket> selectPageRel(@Param("page") IPage<GltUserTicket> page,
                             @Param("param") GltUserTicketParam param);

    /**
     * 查询全部
     *
     * @param param 查询参数
     * @return List<User>
     */
    List<GltUserTicket> selectListRel(@Param("param") GltUserTicketParam param);

    /**
     * 统计用户可用水票总数（sum(available_qty)）
     *
     * @param userId 用户ID
     * @param tenantId 租户ID
     * @return 可用总数
     */
    Integer sumAvailableQtyByUserId(@Param("userId") Integer userId,
                                    @Param("tenantId") Integer tenantId);

    /**
     * 按当前用户锁定水票记录（用于扣减/核销的事务场景）
     */
    @Select("""
        SELECT *
        FROM glt_user_ticket
        WHERE id = #{id}
          AND user_id = #{userId}
          AND tenant_id = #{tenantId}
          AND status = 0
          AND deleted = 0
        LIMIT 1
        FOR UPDATE
        """)
    GltUserTicket selectByIdForUpdate(@Param("id") Integer id,
                                      @Param("userId") Integer userId,
                                      @Param("tenantId") Integer tenantId);

    /**
     * 释放冻结水票（冻结 -> 可用；并累加已释放数量）
     * <p>
     * 返回值为受影响行数：1 表示释放成功；0 表示记录不存在/状态不符/冻结不足。
     */
    @Update("""
        UPDATE glt_user_ticket
        SET available_qty = COALESCE(available_qty, 0) + #{qty},
            frozen_qty = COALESCE(frozen_qty, 0) - #{qty},
            released_qty = COALESCE(released_qty, 0) + #{qty},
            update_time = #{now}
        WHERE id = #{id}
          AND user_id = #{userId}
          AND tenant_id = #{tenantId}
          AND status = 0
          AND deleted = 0
          AND COALESCE(frozen_qty, 0) >= #{qty}
        """)
    int releaseFrozenQty(@Param("id") Integer id,
                         @Param("userId") Integer userId,
                         @Param("tenantId") Integer tenantId,
                         @Param("qty") Integer qty,
                         @Param("now") LocalDateTime now);

}
