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

import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.RefundOrder;
import com.jeequan.jeepay.core.exception.ResponseException;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.sxfpay.SxfpayIsvParams;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.thirdparty.channel.AbstractChannelRefundNoticeService;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

/**
 * 随行付退款回调接口实现类
 *
 * @author xiaoyu
 *
 * @date 2021/12/24 11:31
 */
@Service
@Slf4j
public class SxfpayChannelRefundNoticeService extends AbstractChannelRefundNoticeService {

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

    @Override
    public MutablePair<String, Object> parseParams(HttpServletRequest request, String urlOrderId, NoticeTypeEnum noticeTypeEnum) {
        try {
            JSONObject params = getReqParamJSON();
            // 接收返回参数
            String refundOrderId = params.getString("ordNo");
            return MutablePair.of(refundOrderId, params);
        } catch (Exception e) {
            log.error("error", e);
            throw ResponseException.buildText("ERROR");
        }
    }

    @Override
    public ChannelRetMsg doNotice(HttpServletRequest request, Object params, RefundOrder refundOrder, MchAppConfigContext mchAppConfigContext, NoticeTypeEnum noticeTypeEnum) {
        String logPrefix = "【处理随行付退款回调】";
        try {
            // 获取请求参数
            JSONObject jsonParams = (JSONObject) params;
            log.info("{} 接收参数：{} ", logPrefix, jsonParams);
            // 校验支付回调
            boolean verifyResult = verifyParams(jsonParams, mchAppConfigContext);
            // 验证参数失败
            if(!verifyResult) {
                log.info("{} 验证参数失败， orderId:{}", logPrefix, refundOrder.getRefundOrderId());
                throw ResponseException.buildText("ERROR");
            }
            // 验签成功后判断上游订单状态
            ResponseEntity okResponse = jsonResp(SxfpayKit.ok());
            ChannelRetMsg result = new ChannelRetMsg();
            result.setResponseEntity(okResponse);
            // 渠道订单号
            result.setChannelOrderId(jsonParams.getString("uuid"));
            // 响应数据
            result.setPlatformOrderNo(jsonParams.getString("transactionId"));
            result.setPlatformMchOrderNo(jsonParams.getString("sxfUuid"));
            result.setChannelUserId(jsonParams.getString("openid"));
            result.setChannelErrCode(jsonParams.getString("bizCode"));
            result.setChannelErrMsg(jsonParams.getString("bizMsg"));
            result.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
            return result;
        } catch (Exception e) {
            log.error("error", e);
            throw ResponseException.buildText("ERROR");
        }
    }


    /**
     * 验证随行付退款通知参数
     * @return
     */
    public boolean verifyParams(JSONObject jsonParams, MchAppConfigContext mchAppConfigContext) {
        try {
            String sign = jsonParams.getString("sign");
            if (StringUtils.isEmpty(sign)) {
                log.info("验签参数为空 [sign] :{}", sign);
                return false;
            }
            ConfigContextQueryService configContextQueryService = SpringBeansUtil.getBean(ConfigContextQueryService.class);
            SxfpayIsvParams isvParams = (SxfpayIsvParams) configContextQueryService.queryIsvParams(mchAppConfigContext.getMchApplyment().getIsvNo(), getIfCode());
            return SxfpayKit.checkSign(jsonParams, isvParams);
        }catch (Exception e) {
            log.error("error", e);
            throw ResponseException.buildText("ERROR");
        }
    }
}
