package com.jeequan.jeepay.thirdparty.channel.kqpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.rqrs.AbstractRS;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelJsapiMsg;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.rqrs.payorder.UnifiedOrderRQ;
import com.jeequan.jeepay.thirdparty.channel.AbstractPaymentService;
import com.jeequan.jeepay.thirdparty.channel.kqpay.model.KqpayOrderStatus;
import com.jeequan.jeepay.thirdparty.channel.kqpay.model.KqpayResp;
import com.jeequan.jeepay.thirdparty.channel.kqpay.util.KqpayConst;
import com.jeequan.jeepay.thirdparty.util.PaywayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * TODO
 * 快钱下单
 * @author crystal
 * @date 2023/10/26 14:03
 */
@Service
@Slf4j
public class KqpayPaymentService extends AbstractPaymentService {
    /**
     * 快钱生产环境 最少支付1元
     */
    public Long MIN_PAY_AMT  = 100L;

    @Override
    public String getIfCode() {
        return CS.IF_CODE.KQPAY;
    }

    @Override
    public boolean isSupport(String wayCode) {
        return false;
    }

    @Override
    public String preCheck(UnifiedOrderRQ rq, PayOrder payOrder) {
        return PaywayUtil.getRealPaywayService(this, payOrder.getWayCode()).preCheck(rq, payOrder);
    }

    @Override
    public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        if(payOrder.getAmount() < MIN_PAY_AMT){
            throw new BizException("快钱通道最少需要支付1.00元");
        }
        return PaywayUtil.getRealPaywayService(this, payOrder.getWayCode()).pay(rq, payOrder, mchAppConfigContext);
    }

    /**
     * 解析公共返回参数
     * @param resp
     * @param channelRetMsg
     */
    public void initResult(KqpayResp resp, ChannelRetMsg channelRetMsg){
        JSONObject respBody = resp.getResponseBody();
        String bizResponseCode = respBody.getString("bizResponseCode");
        String bizResponseMessage = respBody.getString("bizResponseMessage");
        channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
        channelRetMsg.setNeedQuery(true);
        channelRetMsg.setPlatformOrderNo(respBody.getString("channelTradeNo"));
        channelRetMsg.setPlatformMchOrderNo(respBody.getString("idTxnCtrl"));
        channelRetMsg.setChannelOrderId(respBody.getString("idOrderCtrl"));
        channelRetMsg.setChannelErrCode(bizResponseCode);
        channelRetMsg.setChannelErrMsg(bizResponseMessage);
        channelRetMsg.setChannelUserId(respBody.getString("thirdPartyBuyerId"));
        channelRetMsg.setPlatformOrderNo(respBody.getString("channelTradeNo"));
        channelRetMsg.setChannelBizData(respBody);
        if(!KqpayConst.BIZ_SUCCESS.equals(bizResponseCode)){
            throw new BizException(bizResponseMessage);
        }
        if(StringUtils.isNotEmpty(respBody.getString("txnStatus"))){
            KqpayOrderStatus txnStatus = KqpayOrderStatus.getVal(respBody.getString("txnStatus"));
            switch (txnStatus){
                case SUCCESS:
                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
                    channelRetMsg.setNeedQuery(true);
                    break;
                case FAIL:
                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                    break;
                case PROCESS:
                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
                    channelRetMsg.setNeedQuery(true);
                    break;
                default:
                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.UNKNOWN);
                    channelRetMsg.setNeedQuery(true);
                    break;
            }
        }
        ChannelJsapiMsg payInfo = respBody.getObject("payInfo", ChannelJsapiMsg.class);
        channelRetMsg.setJsapiMsg(payInfo);
    }
}
