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

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.ResponseException;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.dgpay.DgpayIsvParams;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.thirdparty.channel.AbstractChannelNoticeService;
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 2022/6/13 15:58
 */
@Service
@Slf4j
public class DgpayChannelNoticeService extends AbstractChannelNoticeService {

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

    @Override
    public MutablePair<String, Object> parseParams(HttpServletRequest request, String urlOrderId, NoticeTypeEnum noticeTypeEnum) {

        try {
            // 回调参数body【回调参数顺序固定】
            JSONObject reqParamJSON = getReqParamJSON();
            JSONObject dataJson = reqParamJSON.getJSONObject("resp_data");
            String payOrderId = dataJson.getString("req_seq_id");
            return MutablePair.of(payOrderId, reqParamJSON);

        } catch (Exception e) {
            log.error("error", e);
            throw ResponseException.buildText("ERROR");
        }
    }



    @Override
    public ChannelRetMsg doNotice(HttpServletRequest request, Object params, PayOrder payOrder, MchAppConfigContext mchAppConfigContext, NoticeTypeEnum noticeTypeEnum) {
        try {
            String logPrefix = "【处理[斗拱]支付回调】";
            JSONObject jsonParams = (JSONObject) params;
            String dataJson = jsonParams.getString("resp_data");
            String sign = jsonParams.getString("sign");
            log.info("{} 回调参数, dataJson：{}, sign:{}", logPrefix, dataJson, sign);

            // 公钥参数
            DgpayIsvParams isvParams = (DgpayIsvParams) configContextQueryService.queryIsvParams(mchAppConfigContext.getMchApplyment().getIsvNo(), payOrder.getIfCode());

            // 验证签名
            boolean verifyResult = DgPayKit.verify(dataJson, isvParams.getRsaPublicKey(), sign);

            //验签失败
            if(!verifyResult){
                throw ResponseException.buildText("ERROR");
            }

            //验签成功后判断上游订单状态
            ResponseEntity okResponse = textResp("SUCCESS");

            ChannelRetMsg result = new ChannelRetMsg();

            result.setChannelBizData(jsonParams);
            // 默认支付中
            result.setChannelState(ChannelRetMsg.ChannelState.WAITING);
            // 获取请求参数
            JSONObject respData = jsonParams.getJSONObject("resp_data");
            if(DgPayKit.STATE_SUCCESS_S.equals(respData.getString("trans_stat"))){
                result.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);

            }else if(DgPayKit.STATE_FAIL_F.equals(respData.getString("trans_stat"))){
                result.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                // 交易状态失败存储
                DgPayKit.channelMsgError(respData, result);
            }
            /***
             * D-借记卡，C-贷记卡，0-其他；示例值：D
             */
            String debit_type = respData.getString("debit_type");
            if(StringUtils.isEmpty(debit_type) || "0".equals(debit_type)){
                result.setDrType(CS.DrType.OTHER.getType());
            }else if("D".equals(debit_type)){
                result.setDrType(CS.DrType.DEBIT.getType());
            }else if("C".equals(debit_type)){
                result.setDrType(CS.DrType.CREDIT.getType());
            }else{
                result.setDrType(CS.DrType.OTHER.getType());
            }
            result.setResponseEntity(okResponse);
            result.setChannelOrderId(respData.getString("hf_seq_id"));
            result.setPlatformOrderNo(respData.getString("out_trans_id"));
            result.setPlatformMchOrderNo(respData.getString("party_order_id"));
            return result;
        } catch (Exception e) {
            log.error("error", e);
            throw ResponseException.buildText("ERROR");
        }
    }

}
