package com.bizzan.bitrade.dao;

import com.bizzan.bitrade.dao.base.BaseDao;
import com.bizzan.bitrade.entity.ExperienceGiftWallet;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Optional;

public interface ExperienceGiftWalletDao extends BaseDao<ExperienceGiftWallet> {

    Optional<ExperienceGiftWallet> findByMemberId(Long memberId);

    /** 不存在时初始化全零钱包（IGNORE 防并发重复插入） */
    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query(value =
        "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())",
        nativeQuery = true)
    void initWallet(@Param("memberId") Long memberId);

    /** 申请提现：冻结金额 += amount，待提现 -= amount */
    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query(value =
        "UPDATE experience_gift_wallet SET " +
        "  frozen_amount  = frozen_amount  + :amount, " +
        "  pending_amount = pending_amount - :amount, " +
        "  updated_at     = NOW() " +
        "WHERE member_id = :memberId",
        nativeQuery = true)
    void freezeForWithdraw(@Param("memberId") Long memberId, @Param("amount") BigDecimal amount);

    /** 审核通过：解冻 + 累计已提现 */
    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query(value =
        "UPDATE experience_gift_wallet SET " +
        "  frozen_amount   = frozen_amount   - :amount, " +
        "  total_withdrawn = total_withdrawn + :amount, " +
        "  updated_at      = NOW() " +
        "WHERE member_id = :memberId",
        nativeQuery = true)
    void approveWithdraw(@Param("memberId") Long memberId, @Param("amount") BigDecimal amount);

    /** 审核驳回：解冻 + 归还待提现 */
    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query(value =
        "UPDATE experience_gift_wallet SET " +
        "  frozen_amount  = frozen_amount  - :amount, " +
        "  pending_amount = pending_amount + :amount, " +
        "  updated_at     = NOW() " +
        "WHERE member_id = :memberId",
        nativeQuery = true)
    void rejectWithdraw(@Param("memberId") Long memberId, @Param("amount") BigDecimal amount);

    /** 发券：累计领取面值 += amount（不存在则创建） */
    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query(value =
        "INSERT INTO experience_gift_wallet " +
        "  (member_id, total_received, total_profit, pending_amount, frozen_amount, total_withdrawn, created_at, updated_at) " +
        "VALUES (:memberId, :amount, 0, 0, 0, 0, NOW(), NOW()) " +
        "ON DUPLICATE KEY UPDATE " +
        "  total_received = total_received + :amount, " +
        "  updated_at     = NOW()",
        nativeQuery = true)
    void addReceived(@Param("memberId") Long memberId, @Param("amount") BigDecimal amount);

    /** 平仓盈利入池：total_profit / pending_amount += pnl（不存在则创建） */
    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query(value =
        "INSERT INTO experience_gift_wallet " +
        "  (member_id, total_received, total_profit, pending_amount, frozen_amount, total_withdrawn, created_at, updated_at) " +
        "VALUES (:memberId, 0, :pnl, :pnl, 0, 0, NOW(), NOW()) " +
        "ON DUPLICATE KEY UPDATE " +
        "  total_profit   = total_profit   + :pnl, " +
        "  pending_amount = pending_amount + :pnl, " +
        "  updated_at     = NOW()",
        nativeQuery = true)
    void addProfit(@Param("memberId") Long memberId, @Param("pnl") BigDecimal pnl);
}
