package com.bizzan.bitrade.service;

import com.bizzan.bitrade.dao.ExperienceGiftRecordDao;
import com.bizzan.bitrade.dao.ExperienceGiftWalletDao;
import com.bizzan.bitrade.dao.ExperienceGiftWithdrawDao;
import com.bizzan.bitrade.dao.MemberWalletDao;
import com.bizzan.bitrade.constant.TransactionType;
import com.bizzan.bitrade.entity.ExperienceGiftWallet;
import com.bizzan.bitrade.entity.ExperienceGiftWithdraw;
import com.bizzan.bitrade.entity.ExperienceGiftWithdrawApplyResult;
import com.bizzan.bitrade.entity.ExperienceGiftWithdrawStatus;
import com.bizzan.bitrade.entity.MemberTransaction;
import com.bizzan.bitrade.entity.MemberWallet;
import com.bizzan.bitrade.service.Base.TopBaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class ExperienceGiftWithdrawService extends TopBaseService<ExperienceGiftWithdraw, ExperienceGiftWithdrawDao> {

    /**
     * 提现到账的 USDT coin_id（与 member_wallet.coin_id 对应，根据实际环境配置）
     */
    @Value("${experience.gift.usdt.coin-id:USDT}")
    private String usdtCoinId;

    @Autowired
    private ExperienceGiftWalletDao experienceGiftWalletDao;

    @Autowired
    private ExperienceGiftRecordDao experienceGiftRecordDao;

    @Autowired
    private MemberWalletDao memberWalletDao;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    @Autowired
    private MemberTransactionService memberTransactionService;

    @Autowired
    @Override
    public void setDao(ExperienceGiftWithdrawDao dao) {
        super.setDao(dao);
    }

    // ----------------------------------------------------------------
    // 用户申请提现（pending_amount 全额提现，最低100 USDT）
    // ----------------------------------------------------------------

    @Transactional(rollbackFor = Exception.class)
    public ExperienceGiftWithdrawApplyResult applyWithdraw(Long memberId) {
        // 1. 读取钱包，不存在则自动创建（全零）
        ExperienceGiftWallet wallet = experienceGiftWalletDao.findByMemberId(memberId).orElse(null);
        BigDecimal pendingAmount;
        if (wallet == null) {
            experienceGiftWalletDao.initWallet(memberId);
            pendingAmount = BigDecimal.ZERO;
        } else {
            pendingAmount = wallet.getPendingAmount();
        }

        // 2. 校验最低提现额
        if (pendingAmount.compareTo(new BigDecimal("100")) < 0) {
            return ExperienceGiftWithdrawApplyResult.BELOW_MIN_AMOUNT;
        }

        // 3. 校验是否已有待审核申请
        int pendingCount = dao.countByMemberIdAndStatus(memberId, ExperienceGiftWithdrawStatus.PENDING);
        if (pendingCount > 0) {
            return ExperienceGiftWithdrawApplyResult.PENDING_EXISTS;
        }

        // 4. 创建提现申请
        Date now = new Date();
        ExperienceGiftWithdraw withdraw = new ExperienceGiftWithdraw();
        withdraw.setMemberId(memberId);
        withdraw.setAmount(pendingAmount);
        withdraw.setStatus(ExperienceGiftWithdrawStatus.PENDING);
        withdraw.setApplyAt(now);
        withdraw.setCreatedAt(now);
        withdraw.setUpdatedAt(now);
        dao.save(withdraw);

        // 5. 钱包：冻结金额 += 申请金额，待提现金额 -= 申请金额
        experienceGiftWalletDao.freezeForWithdraw(memberId, pendingAmount);

        return ExperienceGiftWithdrawApplyResult.SUCCESS;
    }

    // ----------------------------------------------------------------
    // 用户自己的提现记录
    // ----------------------------------------------------------------

    public List<ExperienceGiftWithdraw> listByMemberId(Long memberId) {
        return dao.findByMemberIdOrderByApplyAtDesc(memberId);
    }

    // ----------------------------------------------------------------
    // 分页查询
    // ----------------------------------------------------------------

    public Page<Map> pageQuery(Long memberId, Integer status,
                               String applyStartTime, String applyEndTime,
                               String reviewStartTime, String reviewEndTime,
                               int pageNo, int pageSize) {
        return dao.pageQuery(memberId, status, applyStartTime, applyEndTime,
                reviewStartTime, reviewEndTime, pageNo, pageSize);
    }

    // ----------------------------------------------------------------
    // 用户体验金钱包详情（用于弹窗展示）
    // ----------------------------------------------------------------

    public Map<String, Object> getMemberInfo(Long memberId) {
        ExperienceGiftWallet wallet = experienceGiftWalletDao.findByMemberId(memberId).orElse(null);
        BigDecimal inviteReceived = experienceGiftRecordDao.sumInviteReceivedByMemberId(memberId);
        BigDecimal totalLoss = experienceGiftRecordDao.sumLossByMemberId(memberId);

        Map<String, Object> result = new HashMap<>();
        result.put("memberId", memberId);
        result.put("totalReceived",  wallet != null ? wallet.getTotalReceived()  : BigDecimal.ZERO);
        result.put("totalProfit",    wallet != null ? wallet.getTotalProfit()    : BigDecimal.ZERO);
        result.put("pendingAmount",  wallet != null ? wallet.getPendingAmount()  : BigDecimal.ZERO);
        result.put("frozenAmount",   wallet != null ? wallet.getFrozenAmount()   : BigDecimal.ZERO);
        result.put("totalWithdrawn", wallet != null ? wallet.getTotalWithdrawn() : BigDecimal.ZERO);
        result.put("inviteReceived", inviteReceived != null ? inviteReceived : BigDecimal.ZERO);
        result.put("totalLoss",      totalLoss      != null ? totalLoss      : BigDecimal.ZERO);
        return result;
    }

    // ----------------------------------------------------------------
    // 审核（单条）
    // ----------------------------------------------------------------

    @Transactional(rollbackFor = Exception.class)
    public boolean audit(Long id, boolean pass, String remark, Long adminId) {
        ExperienceGiftWithdraw withdraw = dao.findOne(id);
        if (withdraw == null) return false;
        if (withdraw.getStatus() != ExperienceGiftWithdrawStatus.PENDING) return false;

        Date now = new Date();
        withdraw.setReviewedAt(now);
        withdraw.setReviewedBy(adminId);
        withdraw.setUpdatedAt(now);

        if (pass) {
            withdraw.setStatus(ExperienceGiftWithdrawStatus.APPROVED);
            withdraw.setSettledAt(now);
            dao.save(withdraw);

            // experience_gift_wallet：解冻 + 累计已提现
            experienceGiftWalletDao.approveWithdraw(withdraw.getMemberId(), withdraw.getAmount());

            // member_wallet：增加 USDT 余额（到账用户资金账户）
            MemberWallet wallet = memberWalletDao.getMemberWalletByCoinAndMemberId(usdtCoinId, withdraw.getMemberId());
            if (wallet != null) {
                memberWalletDao.increaseBalance(wallet.getId(), withdraw.getAmount());
            }

            // 写入资金流水
            MemberTransaction tx = new MemberTransaction();
            tx.setMemberId(withdraw.getMemberId());
            tx.setAmount(withdraw.getAmount());
            tx.setSymbol("USDT");
            tx.setType(TransactionType.EXPERIENCE_GIFT_WITHDRAW);
            tx.setFee(BigDecimal.ZERO);
            tx.setCreateTime(now);
            memberTransactionService.save(tx);

            // 通知合约引擎刷新内存中的账户余额
            String memberId = withdraw.getMemberId().toString();
            kafkaTemplate.send("trading-account-change", memberId);
            kafkaTemplate.send("follow-account-change", memberId);
        } else {
            withdraw.setStatus(ExperienceGiftWithdrawStatus.REJECTED);
            withdraw.setReviewRemark(remark);
            dao.save(withdraw);

            // experience_gift_wallet：解冻 + 归还待提现
            experienceGiftWalletDao.rejectWithdraw(withdraw.getMemberId(), withdraw.getAmount());
        }
        return true;
    }

    // ----------------------------------------------------------------
    // 批量审核（一键审核）
    // ----------------------------------------------------------------

    @Transactional(rollbackFor = Exception.class)
    public int batchAudit(List<Long> ids, boolean pass, String remark, Long adminId) {
        int count = 0;
        for (Long id : ids) {
            if (audit(id, pass, remark, adminId)) {
                count++;
            }
        }
        return count;
    }
}
