package cn.sikey.hmd.service.alipay;

import cn.sikey.framework.common.exception.ServiceException;
import cn.sikey.framework.common.pojo.CommonResult;
import cn.sikey.hmd.api.hmd.vo.plans.PlansRespVO;
import cn.sikey.hmd.controller.app.alipay.vo.CheckPayReqVO;
import cn.sikey.hmd.enums.PayChannelEnum;
import cn.sikey.hmd.service.AbstractPaymentService;
import cn.sikey.hmd.service.plans.PlansService;
import cn.sikey.hmd.util.PriceUtil;
import cn.sikey.order.api.order.vo.GenerateOrderReqVO;
import cn.sikey.pay.api.alipay.AlipayApi;
import cn.sikey.pay.api.alipay.dto.AliPayTradeDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Objects;

/**
 * @Author: qin
 * @Date: 2025/3/31
 * @Description: alipay
 */
@Service("alipayPaymentService")
@Slf4j
public class AlipayPaymentServiceImpl extends AbstractPaymentService implements AlipayPaymentService {

    @Resource
    private PlansService plansService;

    @Resource
    private AlipayApi alipayApi;

    @Resource
    private TransactionTemplate transactionTemplate;

    private static final String PAY_TYPE = "支付宝";

    /**
     * 手机网站支付
     *
     * @param aliPayTradeDTO alipay
     * @return
     */
    @Override
    public CommonResult<String> alipayTradeWapPay(AliPayTradeDTO aliPayTradeDTO) {
        String merchantProjectApplication = aliPayTradeDTO.getMerchantProjectApplication();
        String deviceId = aliPayTradeDTO.getDeviceId();

        super.checkPayMent(merchantProjectApplication, deviceId, PAY_TYPE);

        final String[] pageRedirectionData = new String[1];
        try {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(@NotNull TransactionStatus status) {
                    try {
                        // 校验支付
                        CheckPayReqVO checkPayReqVO = checkPay(aliPayTradeDTO);
                        // 调用支付服务
                        CommonResult<String> commonResult = alipayApi.alipayTradeWapPay(aliPayTradeDTO);
                        if (!commonResult.getCode().equals(HttpStatus.SC_OK)) {
                            log.warn("[手机网站支付-支付宝]调用支付服务失败");
                            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "调用支付服务失败");
                        }
                        pageRedirectionData[0] = commonResult.getData();
                        // 保存支付记录
                        savePayments(checkPayReqVO.getOrderId(), checkPayReqVO.getPlansId(), deviceId, checkPayReqVO.getAmount(), PayChannelEnum.ALI_PAY.getValue(), merchantProjectApplication);
                    } catch (Exception e) {
                        log.error("[手机网站支付-支付宝]编程时事务异常：{0}", e);
                        status.setRollbackOnly(); // 标记回滚
                        throw e; // 抛出异常，确保事务回滚
                    }
                }
            });
        } catch (Exception e) {
            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
        }

        return CommonResult.success(pageRedirectionData[0]);
    }

    /**
     * 校验支付
     *
     * @param aliPayTradeDTO 阿里交易
     * @return
     */
    private CheckPayReqVO checkPay(AliPayTradeDTO aliPayTradeDTO) {
        // TODO 多次重复点击

        int validity = aliPayTradeDTO.getValidity();
        PlansRespVO plansRespVO = plansService.queryPlans(validity);
        if (Objects.isNull(plansRespVO)) {
            log.warn("[手机网站支付-支付宝]请配置套餐");
            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "请配置套餐");
        }

        int price = plansRespVO.getPrice();

        // 支付金额参数
        aliPayTradeDTO.setTotal_amount(PriceUtil.convertFenToYuan(price));
        String deviceId = aliPayTradeDTO.getDeviceId();

        GenerateOrderReqVO generateOrderReqVO = super.getGenerateOrderReqVO(plansRespVO.getId(), deviceId, aliPayTradeDTO.getMerchantProjectApplication(), price, PAY_TYPE);

        String outTradeNo = generateOrderReqVO.getOrderSn();

        // 支付订单号参数
        aliPayTradeDTO.setOut_trade_no(outTradeNo);

        CheckPayReqVO checkPayReqVO = new CheckPayReqVO();
        checkPayReqVO.setOutTradeNo(outTradeNo);
        checkPayReqVO.setOrderId(generateOrderReqVO.getId());
        checkPayReqVO.setPlansId(plansRespVO.getId());
        checkPayReqVO.setAmount(price);
        return checkPayReqVO;
    }

}


