package org.wfc.payment.pay.wxpay.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.QrCodeKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.wfc.common.core.domain.R;
import org.wfc.common.core.exception.ServiceException;
import org.wfc.payment.pay.wxpay.service.IWxPayService;
import org.wfc.payment.utils.MultipartFileUtil;
import org.wfc.system.api.RemoteFileService;
import org.wfc.system.api.domain.SysFile;
import org.wfc.user.api.RemoteUUserService;
import org.wfc.user.api.domain.vo.UOrderVo;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 微信支付ServiceImpl
 * @author: cyc
 * @since: 2025-03-21
 */
@Service
@Slf4j
public class WxPayServiceImpl implements IWxPayService {

    @Resource
    private RemoteUUserService remoteUUserService;

    @Resource
    private RemoteFileService remoteFileService;

    @Override
    public String scanCode2(HttpServletRequest request, Long orderId, String notifyUrl) {
        R<UOrderVo> orderRes = remoteUUserService.getOrderById(orderId);
        UOrderVo orderVo = orderRes.getData();
        if (orderVo == null) {
            throw new ServiceException("payment.pay.error");
        }

        String totalFee = orderVo.getOrderAmount().multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).toString();
        if (StrUtil.isBlank(totalFee)) {
            throw new ServiceException("payment.pay.error");
        }

        String ip = IpKit.getRealIp(request);
        if (StrUtil.isBlank(ip)) {
            ip = "127.0.0.1";
        }
        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();

        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wxPayApiConfig.getAppId())
                .mch_id(wxPayApiConfig.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .body("WANFI PAY")
                .out_trade_no(WxPayKit.generateStr())
                .total_fee(totalFee)
                .spbill_create_ip(ip)
                .notify_url(notifyUrl)
                .trade_type(TradeType.NATIVE.getTradeType())
                .build()
                .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);

        String xmlResult = WxPayApi.pushOrder(false, params);
        log.info("统一下单:" + xmlResult);

        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);

        String returnCode = result.get("return_code");
        String returnMsg = result.get("return_msg");
        System.out.println(returnMsg);
        if (!WxPayKit.codeIsOk(returnCode)) {
            log.error("error:{}", returnMsg);
            throw new ServiceException("payment.pay.error");
        }
        String resultCode = result.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            log.error("error:{}", returnMsg);
            throw new ServiceException("payment.pay.error");
        }
        //生成预付订单success

        String qrCodeUrl = result.get("code_url");
        String name = "payQRCode2.png";

        String basePath = System.getProperty("user.dir") + File.separator + name;
//        String url = fileBean.getDomain() + fileBean.getPrefix() + File.separator + orderId + File.separator + name;
        FileUtil.mkdir(basePath);

        boolean encode = QrCodeKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
                basePath);
        File uploadFile = new File(basePath);
        MultipartFile multipartFile = MultipartFileUtil.getMultipartFile(uploadFile);
        R<SysFile> fileResult = remoteFileService.upload(multipartFile);
        String url = fileResult.getData().getUrl();
        log.info("qr code file: {}", basePath);
        FileUtil.del(uploadFile);

        if (encode) {
            //在页面上显示
            return url;
        }
        throw new ServiceException("payment.pay.error");
    }

    @Override
    public String payNotify(HttpServletRequest request) {
        String xmlMsg = HttpKit.readData(request);
        log.info("支付通知=" + xmlMsg);
        Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);

        String returnCode = params.get("return_code");

        // 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
        // 注意此处签名方式需与统一下单的签名类型一致
        if (WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.HMACSHA256)) {
            if (WxPayKit.codeIsOk(returnCode)) {
                // 更新订单信息
                // 发送通知等
                Map<String, String> xml = new HashMap<String, String>(2);
                String outTradeNo = params.get("out_trade_no");
                remoteUUserService.paySuccess(Long.valueOf(outTradeNo), "inner");
                xml.put("return_code", "SUCCESS");
                xml.put("return_msg", "OK");
                return WxPayKit.toXml(xml);
            }
        }
        return null;
    }
}
