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

import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.entity.RefundOrder;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.sandpay.SandpayConfig;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRefundLimit;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.rqrs.refund.RefundOrderRQ;
import com.jeequan.jeepay.thirdparty.channel.AbstractRefundService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * 退款接口： 杉德官方
 *
 * @author xiaoyu
 *
 * @date 2021/12/16 11:31
 */
@Slf4j
@Service
public class SandpayRefundService extends AbstractRefundService {

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

    @Override
    public String preCheck(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder) {
        return null;
    }

    @Override
    public ChannelRetMsg refund(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        ChannelRetMsg channelRetMsg = new ChannelRetMsg();
        String logPrefix = "【杉德("+payOrder.getWayCode()+")退款】";
        try {
            String productId = SandpayConfig.WAY_CODE_MAP.get(payOrder.getWayCode());
            if (StringUtils.isEmpty(productId)) {
                log.info("{}支付方式对应的产品编码不存在{}", payOrder.getWayCode(), productId);
                return ChannelRetMsg.sysError("支付方式对应的产品编码不存在");
            }
            JSONObject bodyJson = new JSONObject();
            SandPayKit.setRefundBody(bodyJson, refundOrder, payOrder, getNotifyUrl());
            log.info("退款订单 payorderId:{}, 请求参数reqParams:{}", payOrder.getPayOrderId(), bodyJson);
            JSONObject resJson = SandPayKit.requestServer(bodyJson, SandpayConfig.ORDER_REFUND, SandpayConfig.ORDERREFUND, productId, mchAppConfigContext);
            log.info("退款订单 payorderId:{}, 返回结果:{}", payOrder.getPayOrderId(), resJson);
            if(resJson == null){
                // 状态不明确
                channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.UNKNOWN);
            }
            //请求 & 响应成功， 判断业务逻辑
            JSONObject jsonObject = resJson.getJSONObject("head");
            JSONObject resBodyJson = resJson.getJSONObject("body");
            String status = jsonObject.getString("respCode");
            // 请求成功
            if(SandpayConfig.SUCCESS.equals(status)){
                channelRetMsg.setChannelOrderId(resBodyJson.getString("tradeNo"));
                channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
                log.info("{} >>> 退款处理中", logPrefix);
            }else if (SandpayConfig.WAITING.equals(status)) {
                // 退款处理中
                channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
            }else{
                channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                channelRetMsg.setChannelErrCode(jsonObject.get("respCode").toString());
                channelRetMsg.setChannelErrMsg(jsonObject.get("respMsg").toString());
                log.info("{} >>> 退款失败, {}", logPrefix, resJson);
            }
        }catch (Exception e) {
            // 系统异常
            channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.SYS_ERROR);
        }
        return channelRetMsg;
    }

    @Override
    public ChannelRetMsg query(RefundOrder refundOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        ChannelRetMsg channelRetMsg = new ChannelRetMsg();
        String logPrefix = "【杉德("+refundOrder.getWayCode()+")[无退款接口]退款查询】";
        channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
        log.info("{} >>> 退款中", logPrefix);
        return channelRetMsg;
    }

    /**
     * 退款权限
     * @return
     */
    @Override
    public ChannelRefundLimit isRefundLimit(String settleType,String applyId) {
        return super.isRefundLimit(settleType,applyId);
    }
    @Override
    public void checkPlatAccount(RefundOrder refundOrder) {

    }
}
