package com.bonus.canteen.core.account.v4.app.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.canteen.core.account.v4.app.dto.AppAccInfoV4DTO;
import com.bonus.canteen.core.account.v4.app.dto.PayDto;
import com.bonus.canteen.core.account.v4.app.dto.PaymentDto;
import com.bonus.canteen.core.account.v4.app.mapper.PaymentStageMapper;
import com.bonus.canteen.core.account.v4.app.service.PaymentStageService;
import com.bonus.canteen.core.account.v4.app.vo.AppAccInfoV4VO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * FileName: PaymentStageServiceImpl
 *
 * @author tqzhang
 * Date: 2025/2/20 下午5:13
 * Description:
 */
@Service
public class PaymentStageServiceImpl extends ServiceImpl<PaymentStageMapper, PayDto> implements PaymentStageService {
    @Resource
    private AppAccV4Service appAccV4Service;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult payMoneyForStage(PaymentDto dto) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            AppAccInfoV4DTO appAccInfoV4DTO = new AppAccInfoV4DTO();
            appAccInfoV4DTO.setCustId(dto.getCustId());
            AppAccInfoV4VO vo = appAccV4Service.queryAccInfoForApp(appAccInfoV4DTO);
            // 判断待支付金额和钱包余额关系
            double balance = dto.getMoney() * 100;
            if (vo.getSubsidyBal().compareTo(BigDecimal.valueOf(balance)) < 0) {
                // 补贴余额不足
                double totalMoney = vo.getSubsidyBal().doubleValue() + vo.getWalletBal().doubleValue() + vo.getRedEnvelope().doubleValue();
                if (totalMoney < balance) {
                    return AjaxResult.error("余额不足，请先充值！");
                }
                // 针对补贴余额进行支付
                balance = processPayment(balance, vo.getSubsidyBal().doubleValue(), "2", dto.getCustId(),stringBuilder);
                if (balance > 0) {
                    // 针对红包进行支付
                    balance = processPayment(balance, vo.getRedEnvelope().doubleValue(), "4", dto.getCustId(),stringBuilder);
                    if (balance > 0) {
                        // 针对钱包余额进行支付
                        processPayment(balance, vo.getWalletBal().doubleValue(), "1", dto.getCustId(),stringBuilder);
                    }
                }
            } else {
                // 针对补贴余额进行支付
                processPayment(balance, vo.getSubsidyBal().doubleValue(), "2", dto.getCustId(),stringBuilder);
            }
            //去除最后一个分号
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("支付失败！");
        }
        return AjaxResult.success(stringBuilder.toString());
    }

    private double processPayment(double balance, double availableBalance, String walletId, Long custId,StringBuilder stringBuilder) {
        PayDto payDto = new PayDto();
        payDto.setCustId(custId);
        double amountPaid;
        if (balance > availableBalance) {
            payDto.setWalletBal("0");
            balance -= availableBalance;
            amountPaid = availableBalance;
        } else {
            amountPaid = balance;
            payDto.setWalletBal(String.valueOf(availableBalance - balance));
            balance = 0;
        }
        payDto.setWalletId(walletId);
        this.baseMapper.updateByCustIdAndType(payDto);
        // 记录支付日志
        stringBuilder.append("支付方式:").append(walletId).append("，支付金额:")
                .append(amountPaid).append("；");
        return balance;
    }

    /**
     * 退款
     * @param dto 支付信息
     * @return 退款结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult refundMoneyForStage(PaymentDto dto) {
        List<PayDto> payDtoList = getPayDtoList(dto);
        try {
            for (PayDto payDto : payDtoList) {
                this.baseMapper.refundByCustIdAndType(payDto);
            }
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("退款失败！");
        }
        return AjaxResult.success();
    }

    /**
     * 获取支付信息 支付方式:2，支付金额:500.0；支付方式:4，支付金额:500.0；支付方式:1，支付金额:100.0 转换为支付信息
     * @param dto 支付信息
     * @return 支付信息
     */
    private static List<PayDto> getPayDtoList(PaymentDto dto) {
        String[] walletInfo = dto.getOrderPayInfo().split("；");
        List<PayDto> payDtoList = new ArrayList<>();
        for (String info : walletInfo) {
            String[] split = info.split("，");
            PayDto payDto = new PayDto();
            payDto.setWalletId(split[0].substring(5));
            payDto.setWalletBal(split[1].substring(5));
            payDto.setWalletBalDecimal(new BigDecimal(payDto.getWalletBal()));
            payDto.setCustId(dto.getCustId());
            payDtoList.add(payDto);
        }
        return payDtoList;
    }
}
