package com.wzj.soopin.transaction.kit;

import com.wzj.soopin.member.service.IMemberAccountService;
import com.wzj.soopin.order.service.impl.OrderDelayCancelService;
import com.wzj.soopin.transaction.enums.ClientTypeEnum;
import com.wzj.soopin.transaction.enums.PaymentClientEnum;
import com.wzj.soopin.transaction.enums.PaymentMethodEnum;
import com.wzj.soopin.transaction.kit.dto.PayParam;
import com.wzj.soopin.transaction.kit.dto.PaymentSuccessParams;
import com.wzj.soopin.transaction.kit.params.CashierExecute;
import com.wzj.soopin.transaction.kit.params.dto.CashierParam;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.ResultCode;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.system.service.ISysConfigService;
import org.springframework.stereotype.Component;

import java.time.ZoneId;
import java.time.temporal.TemporalField;
import java.util.Arrays;
import java.util.List;

/**
 * 收银台工具
 *
 * @author Chopper
 * @since 2020-12-19 09:25
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class CashierSupport {
    /**
     * 收银台
     */
    private final List<CashierExecute> cashierExecuteList;
    /**
     * 预存款
     */
    private final  IMemberAccountService memberWalletService;
    /**
     * 配置
     */
    private final ISysConfigService sysConfigService;

    private final OrderDelayCancelService orderDelayCancelService;

    public final



    /**
     * 支付
     *
     * @param paymentMethodEnum 支付渠道枚举
     * @param paymentClientEnum 支付方式枚举
     * @return 支付消息
     */
    R<Object> payment(PaymentMethodEnum paymentMethodEnum, PaymentClientEnum paymentClientEnum,
                      HttpServletRequest request, HttpServletResponse response,
                      PayParam payParam) {
        if (paymentClientEnum == null || paymentMethodEnum == null) {
            throw new ServiceException(ResultCode.PAY_NOT_SUPPORT);
        }
        //获取支付插件
        Payment payment = (Payment) SpringUtils.getBean( paymentMethodEnum.getPlugin());
        log.info("支付请求：客户端：{},支付类型：{},请求：{}", paymentClientEnum.name(), paymentMethodEnum.name(), payParam.toString());

        //支付方式调用
        switch (paymentClientEnum) {
            case H5:
                return payment.h5pay(request, response, payParam);
            case APP:
                return payment.appPay(request, payParam);
            case JSAPI:
                return payment.jsApiPay(request, payParam);
            case NATIVE:
                return payment.nativePay(request, payParam);
            case MP:
                return payment.mpPay(request, payParam);
            default:
                return null;
        }
    }

    /**
     * 支付 支持的支付方式
     *
     * @param client 客户端类型
     * @return 支持的支付方式
     */
    public List<String> support(String client) {

        ClientTypeEnum clientTypeEnum;
        try {
            clientTypeEnum = ClientTypeEnum.valueOf(client);
        } catch (IllegalArgumentException e) {
            throw new ServiceException(ResultCode.PAY_CLIENT_TYPE_ERROR);
        }
        //支付方式 循环获取
//        Setting setting = settingService.get(SettingEnum.PAYMENT_SUPPORT.name());
//        PaymentSupportSetting paymentSupportSetting = JSONUtil.toBean(setting.getSettingValue(), PaymentSupportSetting.class);
//        for (PaymentSupportItem paymentSupportItem : paymentSupportSetting.getPaymentSupportItems()) {
//            if (paymentSupportItem.getClient().equals(clientTypeEnum.name())) {
//                return paymentSupportItem.getSupports();
//            }
//        }

        //从系统配置中获取支付方式  默认为易生支付
        return Arrays.asList(PaymentMethodEnum.EASY_PAY.name());
    }

    /**
     * 支付回调
     *
     * @param paymentMethodEnum 支付渠道枚举
     * @return 回调消息
     */
    public void callback(PaymentMethodEnum paymentMethodEnum,
                         HttpServletRequest request) {

        log.info("支付回调：支付类型：{}", paymentMethodEnum.name());

        //获取支付插件
        Payment payment = (Payment) SpringUtils.getBean((paymentMethodEnum.getPlugin()));
        payment.callBack(request);
    }

    /**
     * 支付通知
     *
     * @param paymentMethodEnum 支付渠道
     */
    public void notify(PaymentMethodEnum paymentMethodEnum,
                       HttpServletRequest request) {

        log.info("支付异步通知：支付类型：{}", paymentMethodEnum.name());

        //获取支付插件
        Payment payment = (Payment) SpringUtils.getBean((paymentMethodEnum.getPlugin()));
        payment.notify(request);
    }

    /**
     * 获取收银台参数
     *
     * @param payParam 支付请求参数
     * @return 收银台参数
     */
    public CashierParam cashierParam(PayParam payParam) {
        for (CashierExecute paramInterface : cashierExecuteList) {
            CashierParam cashierParam = paramInterface.getPaymentParams(payParam);
            log.info("订单编号", payParam.getSn());
            //如果为空，则表示收银台参数初始化不匹配，继续匹配下一条
            if (cashierParam == null) {
                continue;
            }
            //如果订单不需要付款，则抛出异常，直接返回
            if (cashierParam.getPrice() ==null) {
                throw new ServiceException(ResultCode.PAY_UN_WANTED);
            }
            cashierParam.setSupport(support(payParam.getClientType()));
            //获取订单的memberid
            //获取当前余额
//            cashierParam.setWalletValue(memberWalletService.getMemberWallet(UserContext.getCurrentUser().getId()).getMemberWallet());

            // 设置自动取消时间戳
            long cancelTime = cashierParam.getCreateTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() + 30 * 1000; // 30秒
            cashierParam.setAutoCancel(30l);

            // 添加到延迟队列
            long delayMillis = cancelTime - System.currentTimeMillis();
            orderDelayCancelService.addOrderToCancelQueue(payParam.getSn(), delayMillis);

            return cashierParam;
        }
        log.error("错误的支付请求:{}", payParam.toString());
        throw new ServiceException(ResultCode.PAY_CASHIER_ERROR);
    }


    /**
     * 支付结果
     *
     * @param payParam
     * @return
     */
    public Boolean paymentResult(PayParam payParam) {
        for (CashierExecute cashierExecute : cashierExecuteList) {
            if (cashierExecute.cashierEnum().name().equals(payParam.getOrderType())) {
                return cashierExecute.paymentResult(payParam);
            }
        }
        return false;
    }

    public boolean paymentSuccess(PaymentSuccessParams payParam) {
        for (CashierExecute paramInterface : cashierExecuteList) {
            paramInterface.paymentSuccess(payParam);
            log.info("订单编号{}支付成功", payParam.getReceivableNo());
        }
        return true;
    }
}
