package com.seer.teach.pay.app.notify.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.seer.teach.common.enums.pay.PayNotifyTypeEnum;
import com.seer.teach.common.enums.pay.PayOrderSourceEnum;
import com.seer.teach.common.enums.pay.PayStatusEnum;
import com.seer.teach.pay.app.notify.service.AbstractOrderPayNotifyHandler;
import com.seer.teach.pay.entity.CoinRechargeEntity;
import com.seer.teach.pay.entity.PayCoinAccountEntity;
import com.seer.teach.pay.entity.PayNotifyTaskEntity;
import com.seer.teach.pay.entity.PayOrderEntity;
import com.seer.teach.pay.entity.RefundOrderEntity;
import com.seer.teach.pay.service.ICoinConfigService;
import com.seer.teach.pay.service.ICoinRechargeService;
import com.seer.teach.pay.service.IPayCoinAccountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * 学豆充值订单处理策略
 */
@Slf4j
@Component
public class StudyBeanRechargeNotifyHandler extends AbstractOrderPayNotifyHandler {

    @Autowired
    private ICoinRechargeService coinRechargeService;

    @Autowired
    private IPayCoinAccountService userCoinAccountService;

    @Autowired
    private ICoinConfigService coinConfigService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderPayAfterSuccess(PayOrderEntity payOrder) {
        log.info("处理学豆充值订单支付成功，订单号：{}", payOrder.getOrderSn());
        PayNotifyTaskEntity notifyTask = createPayNotifyTask(payOrder, PayNotifyTypeEnum.COIN_RECHARGE_SUCCESS.getCode());

        executeNotifyWithLog(notifyTask, PayNotifyTypeEnum.COIN_RECHARGE_SUCCESS, () -> {
            // 1. 查询充值记录
            CoinRechargeEntity coinRecharge = coinRechargeService.getOneByRechargeSn(payOrder.getMerchantOrderSn());
            if (Objects.isNull(coinRecharge)) {
                log.warn("根据sn[{}]未找到充值记录", payOrder.getMerchantOrderSn());
                return false;
            }

            // 2. 检查支付状态，避免重复处理
            if (coinRecharge.getPayStatus() == PayStatusEnum.SUCCESS.getCode()) {
                log.info("该笔充值已处理");
                return false;
            }

            int userId = coinRecharge.getUserId();
            PayCoinAccountEntity beforeAccount = userCoinAccountService.getByUserId(userId);
            log.info("用户[{}]充值前账户:{}", userId, beforeAccount);

            // 3. 更新充值记录
            boolean coinRechargeUpdateResult = coinRechargeService.update(new LambdaUpdateWrapper<CoinRechargeEntity>().set(PayStatusEnum.SUCCESS.getCode() == payOrder.getStatus(), CoinRechargeEntity::getPaySuccessTime, payOrder.getSuccessTime()).set(CoinRechargeEntity::getPayStatus, payOrder.getStatus()).eq(CoinRechargeEntity::getId, coinRecharge.getId()));
            log.info("更新充值记录结果:{}", coinRechargeUpdateResult);

            if (!coinRechargeUpdateResult) {
                log.error("更新充值记录失败，订单号: {}", payOrder.getOrderSn());
                return false;
            }

            // 4. 计算充值金额,充值金额*兑换比例
            BigDecimal amount = coinConfigService.convertAmountToCoin(coinRecharge.getRechargeAmount(), coinRecharge.getCoinConfigId());

            // 5. 为当前用户充值
            boolean rechargeResult = userCoinAccountService.recharge(userId, amount);
            PayCoinAccountEntity afterAccount = userCoinAccountService.getByUserId(userId);
            log.info("用户[{}]充值后账户:{}", userId, afterAccount);

            // 6. 记录充值结果日志
            if (rechargeResult) {
                log.info("用户 {} 充值成功，充值金额: {}", userId, amount);
            } else {
                log.error("用户 {} 充值失败，充值金额: {}", userId, amount);
            }
            return rechargeResult;
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderPayAfterFail(PayOrderEntity payOrder) {
        log.info("处理学豆充值订单支付失败，订单号：{}", payOrder.getOrderSn());
        PayNotifyTaskEntity notifyTask = createPayNotifyTask(payOrder, PayNotifyTypeEnum.COIN_RECHARGE_FAIL.getCode());

        executeNotifyWithLog(notifyTask, PayNotifyTypeEnum.COIN_RECHARGE_FAIL, () -> {
            // 1. 查询充值记录
            CoinRechargeEntity coinRecharge = coinRechargeService.getOne(new LambdaQueryWrapper<CoinRechargeEntity>().eq(CoinRechargeEntity::getRechargeSn, payOrder.getMerchantOrderSn()));

            if (Objects.isNull(coinRecharge)) {
                log.warn("根据sn[{}]未找到充值记录", payOrder.getMerchantOrderSn());
                return false;
            }

            // 2. 检查支付状态，避免重复处理
            if (coinRecharge.getPayStatus() == PayStatusEnum.PAY_FAILED.getCode()) {
                log.info("该笔充值支付失败已处理");
                return false;
            }

            // 3. 更新充值记录状态为支付失败
            boolean coinRechargeUpdateResult = coinRechargeService.update(new LambdaUpdateWrapper<CoinRechargeEntity>().set(CoinRechargeEntity::getPayStatus, PayStatusEnum.PAY_FAILED.getCode()).eq(CoinRechargeEntity::getId, coinRecharge.getId()));
            log.info("更新充值记录支付失败状态结果:{}", coinRechargeUpdateResult);

            if (coinRechargeUpdateResult) {
                log.info("用户 {} 充值支付失败，订单号: {}", coinRecharge.getUserId(), payOrder.getOrderSn());
            }
            return coinRechargeUpdateResult;
        });

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderRefundAfterSuccess(RefundOrderEntity refundOrder) {
        log.info("处理学豆充值退款订单成功，退款订单号：{}", refundOrder.getRefundSn());
        PayNotifyTaskEntity notifyTask = createRefundNotifyTask(refundOrder, PayNotifyTypeEnum.COIN_REFUND_SUCCESS.getCode());

        executeNotifyWithLog(notifyTask, PayNotifyTypeEnum.COIN_RECHARGE_FAIL, () -> {
            // 1. 查询充值记录
            CoinRechargeEntity coinRecharge = coinRechargeService.getOne(new LambdaQueryWrapper<CoinRechargeEntity>().eq(CoinRechargeEntity::getRechargeSn, refundOrder.getMerchantOrderSn()));

            if (Objects.isNull(coinRecharge)) {
                log.warn("根据sn[{}]未找到充值记录", refundOrder.getMerchantOrderSn());
                return false;
            }

            // 2. 检查退款状态，避免重复处理
            if (coinRecharge.getPayStatus() == PayStatusEnum.WECHAT_REFUND_SUCCESS.getCode()) {
                log.info("该笔退款已处理");
                return false;
            }

            int userId = coinRecharge.getUserId();
            PayCoinAccountEntity beforeAccount = userCoinAccountService.getByUserId(userId);
            log.info("用户[{}]退款前账户:{}", userId, beforeAccount);

            // 3. 更新充值记录状态为已退款
            boolean coinRechargeUpdateResult = coinRechargeService.update(new LambdaUpdateWrapper<CoinRechargeEntity>().set(CoinRechargeEntity::getPayStatus, PayStatusEnum.WECHAT_REFUND_SUCCESS.getCode()).set(CoinRechargeEntity::getPaySuccessTime, refundOrder.getSuccessTime()).eq(CoinRechargeEntity::getId, coinRecharge.getId()));
            log.info("更新充值记录退款状态结果:{}", coinRechargeUpdateResult);

            if (!coinRechargeUpdateResult) {
                log.error("更新充值记录退款状态失败，退款订单号: {}", refundOrder.getRefundSn());
                return false;
            }
            // 4. 计算退款金额
            BigDecimal refundAmount = new BigDecimal(refundOrder.getRefundAmount());

            // 5. 为用户退款（扣减账户余额）
            return userCoinAccountService.deductBalance(userId, refundAmount);
        });

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderRefundAfterFail(RefundOrderEntity refundOrder) {
        log.info("处理学豆充值退款失败订单，退款订单号：{}", refundOrder.getRefundSn());
        PayNotifyTaskEntity notifyTask = createRefundNotifyTask(refundOrder, PayNotifyTypeEnum.COIN_REFUND_FAIL.getCode());

        executeNotifyWithLog(notifyTask, PayNotifyTypeEnum.COIN_RECHARGE_FAIL, () -> {
            // 1. 查询充值记录
            CoinRechargeEntity coinRecharge = coinRechargeService.getOne(new LambdaQueryWrapper<CoinRechargeEntity>().eq(CoinRechargeEntity::getRechargeSn, refundOrder.getMerchantOrderSn()));

            if (Objects.isNull(coinRecharge)) {
                log.warn("根据sn[{}]未找到充值记录", refundOrder.getMerchantOrderSn());
                return false;
            }

            // 2. 检查退款状态，避免重复处理
            if (coinRecharge.getPayStatus() == PayStatusEnum.WECHAT_REFUND_FAILED.getCode()) {
                log.info("该笔退款失败已处理");
                return false;
            }

            // 3. 更新充值记录状态为退款失败
            boolean coinRechargeUpdateResult = coinRechargeService.update(new LambdaUpdateWrapper<CoinRechargeEntity>().set(CoinRechargeEntity::getPayStatus, PayStatusEnum.WECHAT_REFUND_FAILED.getCode()).eq(CoinRechargeEntity::getId, coinRecharge.getId()));
            log.info("更新充值记录退款失败状态结果:{}", coinRechargeUpdateResult);
            return coinRechargeUpdateResult;
        });


    }

    @Override
    public PayOrderSourceEnum getOrderSource() {
        return PayOrderSourceEnum.STUDY_BEAN_RECHARGE;
    }


}