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

import cn.dev33.satoken.stp.StpUtil;
import com.seer.teach.common.enums.pay.PayChannelEnum;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.enums.pay.PayOrderSourceEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.common.utils.MoneyUtil;
import com.seer.teach.common.utils.OrderIdGenerator;
import com.seer.teach.pay.app.wallet.req.AppCoinRechargeReq;
import com.seer.teach.pay.app.recharge.service.IAppRechargeService;
import com.seer.teach.pay.entity.CoinConfigEntity;
import com.seer.teach.pay.entity.CoinRechargeEntity;
import com.seer.teach.pay.entity.PayOrderEntity;
import com.seer.teach.common.enums.pay.PayStatusEnum;
import com.seer.teach.pay.service.ICoinConfigService;
import com.seer.teach.pay.service.ICoinRechargeService;
import com.seer.teach.pay.service.IPayOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Slf4j
@Service
@RequiredArgsConstructor
public class AppRechargeServiceImpl implements IAppRechargeService {

    private final ICoinConfigService coinConfigService;

    private final ICoinRechargeService coinRechargeService;

    private final IPayOrderService payOrderService;

    @Transactional(rollbackFor = Exception.class, timeout = 120)
    @Override
    public String createWalletRechargePayOrder(AppCoinRechargeReq appCoinRechargeReq) {
        log.info("微信支付开始");
        int userId = StpUtil.getLoginIdAsInt();
        String coinRechargeSn = OrderIdGenerator.generateOrderId(OrderIdGenerator.PAY_RECHARGE_ORDER_PREFIX);
        log.info("学豆充值SN:{}", coinRechargeSn);
        CoinConfigEntity coinConfig = coinConfigService.getActiveAndLatestCoinConfig();
        AssertUtils.notNull(coinConfig, ResultCodeEnum.COIN_CONFIG_NOT_FOUND);
        log.info("获取学豆配置:{}", coinConfig);
        // 插入充值记录
        CoinRechargeEntity coinRecharge = new CoinRechargeEntity();
        coinRecharge.setCoinConfigId(coinConfig.getId());
        coinRecharge.setRechargeTime(LocalDateTime.now());
        coinRecharge.setRechargeSn(coinRechargeSn);
        coinRecharge.setUserId(userId);
        coinRecharge.setRechargeAmount(appCoinRechargeReq.getRechargeAmount());
        // 支付状态;0-付款中;1-已付款;2-付款失败;3-退款
        coinRecharge.setPayStatus(PayStatusEnum.PENDING.getCode());

        BigDecimal rechargeCoin = coinConfigService.convertAmountToCoin(appCoinRechargeReq.getRechargeAmount(), coinConfig);
        log.info("金额[{}]转换学豆:{}", appCoinRechargeReq.getRechargeAmount(), rechargeCoin);
        coinRecharge.setRechargeCoin(rechargeCoin);
        boolean rechargeResult = coinRechargeService.save(coinRecharge);
        log.info("插入充值记录:{}", rechargeResult);

        Long totalAmount = MoneyUtil.yuanToCent(appCoinRechargeReq.getRechargeAmount());
        //计算充值金额
        log.info("充值金额[{}]分", totalAmount);
        PayOrderEntity payOrderEntity = new PayOrderEntity();
        payOrderEntity.setUserId(userId);
        payOrderEntity.setMerchantOrderId(String.valueOf(coinRecharge.getId()));
        payOrderEntity.setMerchantOrderSn(coinRecharge.getRechargeSn());
        payOrderEntity.setChannelCode(PayChannelEnum.WECHAT_JSAPI.getCode());
        payOrderEntity.setBody(coinConfig.getCoinName());
        payOrderEntity.setSubject(coinConfig.getCoinName());
        payOrderEntity.setTotalAmount(totalAmount);
        payOrderEntity.setTotalCoin(rechargeCoin);
        payOrderEntity.setOrderSource(PayOrderSourceEnum.STUDY_BEAN_RECHARGE.getCode());
        Integer parOrderId = payOrderService.createOrder(payOrderEntity);
        log.info("创建订单结果:{}", parOrderId);
        return coinRecharge.getRechargeSn();
    }

}
