package com.czg.impl;

import com.alibaba.fastjson2.JSONObject;
import com.czg.PayAdapter;
import com.czg.PayManager;
import com.czg.constant.PayChannelCst;
import com.czg.enums.CzgPayEnum;
import com.czg.exception.CzgException;
import com.czg.pay.*;
import com.czg.resp.CzgResult;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * 原生支付适配器
 *
 * @author ww
 * @date 2023/10/20 14:20
 */
@Slf4j
public class NativePayAdapter implements PayAdapter {


    @Override
    public String getChannel() {
        return PayChannelCst.NATIVE;
    }

    @Override
    public CzgResult<Map<String, Object>> pay(@NonNull CzgPayEnum payType, String payData, String domain, String notifyUrl, CzgPayBaseReq bizData) {
        try {
            NativeMerchantDTO merchantDTO = getMerchantDTO(payData);
            return switch (payType) {
//                case H5_PAY:
//                    return h5Pay(merchantDTO, domain, notifyUrl, bizData);
                case JS_PAY -> jsPay(merchantDTO, notifyUrl, bizData);
                case LT_PAY -> jsPay(merchantDTO, notifyUrl, bizData);
//                case SCAN_PAY:
//                    return scanPay(merchantDTO, domain, notifyUrl, bizData);
                case MICRO_PAY ->
                    //扫码支付 扫描码
                        barPay(merchantDTO, notifyUrl, bizData);
                default -> throw new CzgException("原生支付不支持该支付方式: " + bizData.getPayType());
            };
        } catch (Exception e) {
            log.error("聚合支付处理失败: {}", e.getMessage(), e);
            return CzgResult.failure("聚合支付处理失败: " + e.getMessage());
        }
    }

    @Override
    public CzgResult<RefundRespDTO> refund(String domain, String payData, CzgRefundReq bizData) {
        NativeMerchantDTO merchantDTO = getMerchantDTO(payData);
        return CzgResult.success(PayManager.refund(bizData, bizData.getNotifyUrl(), merchantDTO));
    }

    @Override
    public CzgResult<QueryOrderRespDTO> queryPayOrder(String domain, String payData, String payOrderId, String mchOrderNo, String platform) {
        NativeMerchantDTO merchantDTO = getMerchantDTO(payData);
        QueryOrderRespDTO respDTO = PayManager.queryOrderStatus(platform, mchOrderNo, merchantDTO);
        return CzgResult.success(respDTO);
    }

    @Override
    public CzgResult<RefundRespDTO> queryRefund(String domain, String payData, String mchRefundNo, String refundOrderId) {
        return null;
    }

    private CzgResult<Map<String, Object>> jsPay(NativeMerchantDTO merchantDTO, String notifyUrl, CzgPayBaseReq bizData) {
        bizData.setNotifyUrl(notifyUrl);
        return CzgResult.success(PayManager.jsapiPay(bizData, merchantDTO));
    }

    private CzgResult<Map<String, Object>> barPay(NativeMerchantDTO merchantDTO, String notifyUrl, CzgPayBaseReq bizData) {
        bizData.setNotifyUrl(notifyUrl);
        return CzgResult.success(PayManager.barPay(bizData, merchantDTO));
    }

    private NativeMerchantDTO getMerchantDTO(String payData) {
        return JSONObject.parseObject(payData, NativeMerchantDTO.class);
    }
}
