package com.datacenter.mapper;

import com.datacenter.job.vo.InviteGrantCandidateVo;
import org.apache.ibatis.annotations.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Mapper
public interface ExperienceGiftInviteGrantMapper {

    /**
     * 查询过去 35 分钟内已平仓、满足直邀发放条件、且尚未发放过的仓位候选列表。
     * 详细 SQL 见 ExperienceGiftInviteGrantMapper.xml
     */
    List<InviteGrantCandidateVo> findQualifyingCandidates();

    /** 查询邀请人在指定产品上已领取的体验金张数（用于 per_user_limit 检查） */
    @Select("SELECT COUNT(*) FROM experience_gift_record " +
            "WHERE member_id = #{inviterId} AND product_id = #{productId}")
    int countGrantedByInviterAndProduct(@Param("inviterId") Long inviterId,
                                        @Param("productId") Long productId);

    /** 查询指定被邀人在指定产品上是否已触发过直邀发放（inviter_id 字段存的是被邀人 ID） */
    @Select("SELECT COUNT(*) FROM experience_gift_record " +
            "WHERE inviter_id = #{memberId} AND product_id = #{productId}")
    int countGrantedByInviteeAndProduct(@Param("memberId") Long memberId,
                                        @Param("productId") Long productId);

    /** 查询产品当前已发放张数（事务内二次确认，防并发超发） */
    @Select("SELECT issued_count FROM experience_gift_product WHERE id = #{productId}")
    Integer getProductIssuedCount(@Param("productId") Long productId);

    /** 插入体验金发放记录（memberId=邀请人，inviterId=被邀人） */
    @Insert("INSERT INTO experience_gift_record " +
            "(product_id, product_name, member_id, inviter_id, amount, max_profit, leverage, validity_days, " +
            " grant_type, status, expire_at, client_ip, created_at, updated_at) " +
            "VALUES " +
            "(#{productId}, #{productName}, #{inviterId}, #{memberId}, #{amount}, #{maxProfitPerCard}, #{leverage}, " +
            " #{validityDays}, 1, 0, #{expireAt}, #{clientIp}, #{now}, #{now})")
    void insertRecord(@Param("productId") Long productId,
                      @Param("productName") String productName,
                      @Param("inviterId") Long inviterId,
                      @Param("memberId") Long memberId,
                      @Param("amount") BigDecimal amount,
                      @Param("maxProfitPerCard") BigDecimal maxProfitPerCard,
                      @Param("leverage") Integer leverage,
                      @Param("validityDays") Integer validityDays,
                      @Param("expireAt") Date expireAt,
                      @Param("clientIp") String clientIp,
                      @Param("now") Date now);

    /** 初始化体验金钱包（已存在则忽略） */
    @Insert("INSERT IGNORE INTO experience_gift_wallet " +
            "(member_id, total_received, total_profit, pending_amount, frozen_amount, total_withdrawn, created_at, updated_at) " +
            "VALUES (#{memberId}, 0, 0, 0, 0, 0, NOW(), NOW())")
    void initWallet(@Param("memberId") Long memberId);

    /** 累加钱包已领取金额 */
    @Update("UPDATE experience_gift_wallet " +
            "SET total_received = total_received + #{amount}, updated_at = NOW() " +
            "WHERE member_id = #{memberId}")
    void addReceivedToWallet(@Param("memberId") Long memberId,
                             @Param("amount") BigDecimal amount);

    /** 产品已发放张数 +1 */
    @Update("UPDATE experience_gift_product " +
            "SET issued_count = issued_count + 1, updated_at = NOW() " +
            "WHERE id = #{productId}")
    void incrementProductIssuedCount(@Param("productId") Long productId);

    /**
     * 插入去重日志，UNIQUE KEY(position_id, product_id)。
     * 若已存在则抛 DuplicateKeyException，由调用方捕获并跳过。
     */
    @Insert("INSERT INTO experience_gift_invite_grant_log (position_id, product_id, inviter_id, created_at) " +
            "VALUES (#{positionId}, #{productId}, #{inviterId}, #{createdAt})")
    void insertGrantLog(@Param("positionId") Long positionId,
                        @Param("productId") Long productId,
                        @Param("inviterId") Long inviterId,
                        @Param("createdAt") Date createdAt);
}
