package com.kxs.common.pay.service.ali;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.kxs.common.core.exception.GlobalCustomerException;
import com.kxs.common.pay.config.AliPayAccountConfig;
import com.kxs.common.pay.enums.PayConstants;
import com.kxs.common.pay.enums.PayPlatformEnum;
import com.kxs.common.pay.enums.PayStatusCommEnum;
import com.kxs.common.pay.handlers.PayMessageHandler;
import com.kxs.common.pay.model.*;
import com.kxs.common.pay.service.PayService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 支付宝支付服务
 *
 * @author 没秃顶的码农
 * @date 2024-04-24
 */
@RequiredArgsConstructor
@Slf4j
public class AliPayService implements PayService {

    private final AlipayClient alipayClient;

    private final AliPayAccountConfig aliPayAccountConfig;

    @Override
    public PayResponse appPay(PayRequest payReq) throws AlipayApiException {

        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //回掉地址
        request.setNotifyUrl(aliPayAccountConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        //支付信息
        bizContent.put("out_trade_no", payReq.getOutTradeNo());
        bizContent.put("total_amount", payReq.getTotalAmount());
        bizContent.put("subject", payReq.getSubject());
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");
        bizContent.put("time_expire", LocalDateTimeUtil.format(LocalDateTime.now().plusMinutes(20), DatePattern.NORM_DATETIME_PATTERN));
        //商品信息
        if(StrUtil.isNotBlank(payReq.getGoodsDetail())){
            bizContent.put("goods_detail", payReq.getPassbackParams());
        }
        //扩展参数
        if(StrUtil.isNotBlank(payReq.getPassbackParams())){
            bizContent.put("passback_params", payReq.getPassbackParams());
        }
        request.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        String orderStr = response.getBody();
        if(response.isSuccess()){
            return PayResponse.builder()
                    .result(orderStr)
                    .payPlatformEnum(PayPlatformEnum.ALIPAY).build();
        }
        return PayResponse.builder().payPlatformEnum(PayPlatformEnum.ALIPAY).build();
    }

    @Override
    public QueryResponse query(QueryRequest queryReq) throws AlipayApiException {
        // 构造请求参数以调用接口
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();

        // 设置订单支付时传入的商户订单号
        model.setOutTradeNo(queryReq.getOutTradeNo());

        request.setBizModel(model);
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            return QueryResponse.builder()
                    .outTradeNo(response.getOutTradeNo())
                    .tradeNo(response.getTradeNo())
                    .buyerLogonId(response.getBuyerLogonId())
                    .tradeStatus(PayStatusCommEnum.valueOf(response.getTradeStatus()))
                    .payPlatformEnum(PayPlatformEnum.ALIPAY).build();
        }
        return null;
    }


    @Override
    public String payBack(HttpServletRequest request) throws AlipayApiException {

        Map<String, String> noticeParams = getNoticeParams(request);

        boolean signVerified = AlipaySignature.rsaCheckV2(noticeParams, aliPayAccountConfig.getAliPayPublicKey(), "UTF-8", aliPayAccountConfig.getSignType());
        if (!signVerified) {
            log.error("alipay notifies that signature verification failed");
            return PayConstants.ALI_PAY_FAIL;
        }
        AliPayMessage aliPayMessage = BeanUtil.toBean(noticeParams, AliPayMessage.class);
        aliPayMessage.setPayMessage(noticeParams);
        aliPayMessage.setPayType(PayPlatformEnum.ALIPAY);
        PayMessageHandler payMessageHandler = getPayMessageHandler(PayPlatformEnum.ALIPAY);
        return payMessageHandler.handle(aliPayMessage, this);
    }


    /**
     * 获取通知参数
     *
     * @param request 请求
     * @return {@link Map}< {@link String} , {@link String}>
     */
    public Map< String , String> getNoticeParams(HttpServletRequest request) {
        Map< String , String > params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        return params;
    }

}
