package cn.sikey.hmd.service.wechat;

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.order.api.order.vo.GenerateOrderReqVO;
import cn.sikey.pay.api.wechat.WechatApi;
import cn.sikey.pay.api.wechat.dto.WechatPayTradeDTO;
import com.wechat.pay.java.service.payments.h5.model.Amount;
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
@Slf4j
public class WechatPaymentServiceImpl extends AbstractPaymentService implements WechatPaymentService {

    @Resource
    private PlansService plansService;

    @Resource
    private WechatApi wechatApi;

    @Resource
    private TransactionTemplate transactionTemplate;

    private static final String PAY_TYPE = "微信";

    /**
     * 手机网站支付
     *
     * @param wechatPayTradeDTO wechat
     * @return
     */
    @Override
    public CommonResult<String> payTransactionsH5(WechatPayTradeDTO wechatPayTradeDTO) {
        String merchantProjectApplication = wechatPayTradeDTO.getMerchantProjectApplication();
        // 校验套餐有效期（1:1年2:终身）
        String deviceId = wechatPayTradeDTO.getDeviceId();

        super.checkPayMent(merchantProjectApplication, deviceId, PAY_TYPE);

        final String[] pageRedirectionData = new String[1];
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(@NotNull TransactionStatus status) {
                try {
                    // 校验支付
                    CheckPayReqVO checkPayReqVO = checkPay(wechatPayTradeDTO);
                    // 调用支付服务
                    CommonResult<String> commonResult = wechatApi.payTransactionsH5(wechatPayTradeDTO);
                    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.WE_CHAT.getValue(), merchantProjectApplication);
                } catch (Exception e) {
                    log.error("[手机网站支付-微信，回调]编程时事务异常：{0}", e);
                    status.setRollbackOnly(); // 标记回滚
                    throw e; // 抛出异常，确保事务回滚
                }
            }
        });

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

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

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

        int price = plansRespVO.getPrice();
        Amount amount = new Amount();
        amount.setTotal(price);
        // 支付金额参数
        wechatPayTradeDTO.setAmount(amount);

        String deviceId = wechatPayTradeDTO.getDeviceId();

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

        String outTradeNo = generateOrderReqVO.getOrderSn();

        // 支付订单号参数
        wechatPayTradeDTO.setOutTradeNo(outTradeNo);

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

}
