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

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Pair;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.ChannelAccountCashoutRecord;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.cashout.CashoutRetMsg;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.dgpay.DgpayIsvParams;
import com.jeequan.jeepay.core.model.params.dgpay.DgpayIsvsubMchParams;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.thirdparty.channel.AbstractChannelAccountService;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
* 提现接口： 斗拱
*
* @author zx
*
* @date 2023/6/14 16:19
*/
@Slf4j
@Service
public class DgpayChannelAccountService extends AbstractChannelAccountService {

    @Autowired private ConfigContextQueryService configContextQueryService;

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

    @Override
    public Pair<String, Long> queryBalanceAmount(MchAppConfigContext mchAppConfigContext, String ifCode) {
        String logPrefix = "斗拱商户余额查询";

        DgpayIsvsubMchParams subMchParams = (DgpayIsvsubMchParams) configContextQueryService.queryIsvsubMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), ifCode);
        if (subMchParams == null) {
            throw new BizException("斗拱商户余额查询，商户参数未配置");
        }

        JSONObject reqParams = new JSONObject();
        // 请求日期
        reqParams.put("req_date", DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
        // 请求流水号
        reqParams.put("req_seq_id", DateKit.currentTimeMillis());
        // 商户号
        reqParams.put("huifu_id", subMchParams.getHuifuId());

        log.info(logPrefix);
        JSONObject response = DgPayKit.request(mchAppConfigContext, reqParams, "/trade/acctpayment/balance/query", ifCode);
        JSONObject jsonData = response.getJSONObject("data");

        Long balanceAmt = 0L;
        // 响应成功
        if (DgPayKit.STATE_SUCCESS.equals(jsonData.getString("resp_code"))) {
            // 账户信息列表
            JSONArray infoList = jsonData.getJSONArray("acctInfo_list");
            for (int i = 0; i < infoList.size(); i++) {
                JSONObject infoJson = JSONObject.parseObject(infoList.get(i).toString());
                // 查询基本账户类型
                if ("01".equals(infoJson.getString("acct_type"))) {
                    balanceAmt = Long.parseLong(AmountUtil.convertDollar2Cent(infoJson.getString("balance_amt")));
                }
            }
        }

        return new Pair<>(subMchParams.getHuifuId(), balanceAmt);
    }

    @Override
    public CashoutRetMsg cashout(ChannelAccountCashoutRecord cashoutRecord, MchAppConfigContext mchAppConfigContext, String ifCode) {
        String logPrefix = "斗拱商户提现";
        CashoutRetMsg cashoutRetMsg = new CashoutRetMsg();

        DgpayIsvParams isvParams = (DgpayIsvParams) configContextQueryService.queryIsvParams(mchAppConfigContext.getMchApplyment().getIsvNo(), ifCode);
        DgpayIsvsubMchParams subMchParams = (DgpayIsvsubMchParams) configContextQueryService.queryIsvsubMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), ifCode);
        if (subMchParams == null) {
            throw new BizException("斗拱商户提现，商户参数未配置");
        }

        try {
            if ("0".equals(isvParams.getMchSettManual())) {
                throw new BizException("斗拱商户提现，服务商未开启取现配置");
            }
            JSONObject reqParams = new JSONObject();
            // 请求流水号
            reqParams.put("req_seq_id", cashoutRecord.getRid());
            // 请求日期
            reqParams.put("req_date", DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
            // 商户号
            reqParams.put("huifu_id", subMchParams.getHuifuId());
            // 到账类型
            reqParams.put("into_acct_date_type", isvParams.getMchSettManual());
            // 取现卡序列号
            reqParams.put("token_no", subMchParams.getTokenNo());
            // 取现金额
            reqParams.put("cash_amt", AmountUtil.convertCent2Dollar(cashoutRecord.getCashoutAmount()));
            // 异步通知地址
            reqParams.put("notify_url", getNotifyUrl());

            log.info(logPrefix);
            JSONObject response = DgPayKit.request(mchAppConfigContext, reqParams, "/trade/settlement/enchashment", ifCode);
            JSONObject dataJSON = response.getJSONObject("data");

            // 响应成功
            if (DgPayKit.STATE_SUCCESS.equals(dataJSON.getString("resp_code"))) {
                // 交易状态  S：成功    F：失败    P：处理中
                String transStat = dataJSON.getString("trans_stat");
                if (DgPayKit.STATE_SUCCESS_S.equals(transStat)) {
                    cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
                    cashoutRetMsg.setChannelOrderId(dataJSON.getString("hf_seq_id")); // 渠道提现单号

                }else if (DgPayKit.STATE_FAIL_F.equals(transStat)) {
                    cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                    cashoutRetMsg.setChannelErrCode(dataJSON.getString("resp_code"));
                    cashoutRetMsg.setChannelErrMsg(dataJSON.getString("resp_desc"));

                }else {
                    cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);

                }
            }else {
                cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                cashoutRetMsg.setChannelErrMsg(dataJSON.getString("resp_desc"));
            }

            return cashoutRetMsg;

        } catch (Exception e) {
            cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
            cashoutRetMsg.setChannelErrMsg(e.getMessage());
            return cashoutRetMsg;
        }

    }

    @Override
    public CashoutRetMsg cashoutQuery(ChannelAccountCashoutRecord cashoutRecord, MchAppConfigContext mchAppConfigContext, String ifCode) {
        String logPrefix = "斗拱商户提现结果查询";
        CashoutRetMsg cashoutRetMsg = new CashoutRetMsg();

        DgpayIsvsubMchParams subMchParams = (DgpayIsvsubMchParams) configContextQueryService.queryIsvsubMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), ifCode);
        if (subMchParams == null) {
            throw new BizException("斗拱商户提现结果查询失败，商户参数未配置");
        }

        try {
            JSONObject reqParams = new JSONObject();
            // 商户号
            reqParams.put("huifu_id", subMchParams.getHuifuId());
            // 原交易请求日期
            reqParams.put("org_req_date", DateUtil.format(cashoutRecord.getCreatedAt(), DatePattern.PURE_DATE_PATTERN));
            // 原交易请求流水号
            reqParams.put("org_req_seq_id", cashoutRecord.getRid());

            log.info(logPrefix);
            JSONObject response = DgPayKit.request(mchAppConfigContext, reqParams, "/trade/settlement/query", ifCode);

            JSONObject dataJSON = response.getJSONObject("data");

            // 响应成功
            if (DgPayKit.STATE_SUCCESS.equals(dataJSON.getString("resp_code"))) {
                // 交易状态  S：成功    F：失败    P：处理中
                String transStat = dataJSON.getString("trans_status");
                if (DgPayKit.STATE_SUCCESS_S.equals(transStat)) {
                    cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
                    cashoutRetMsg.setChannelOrderId(dataJSON.getString("hf_seq_id")); // 渠道提现单号

                }else if (DgPayKit.STATE_FAIL_F.equals(transStat)) {
                    cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                    cashoutRetMsg.setChannelErrCode(dataJSON.getString("resp_code"));
                    cashoutRetMsg.setChannelErrMsg(dataJSON.getString("resp_desc"));

                }else {
                    cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);

                }
            }else {
                cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                cashoutRetMsg.setChannelErrMsg(dataJSON.getString("resp_desc"));
            }

            return cashoutRetMsg;

        } catch (Exception e) {
            cashoutRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
            cashoutRetMsg.setChannelErrMsg(e.getMessage());
            return cashoutRetMsg;
        }
    }

}
