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

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.model.params.dgpay.DgpayIsvParams;
import com.jeequan.jeepay.core.model.rqrs.mch.ChannelMchRq;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.rqrs.settle.ChannelSettleRq;
import com.jeequan.jeepay.db.entity.SettleInfo;
import com.jeequan.jeepay.thirdparty.channel.AbstractMchApiService;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * TODO
 *
 * @author crystal
 * @date 2023/12/4 10:47
 */
@Service
@Slf4j
public class DgpayMchApiService extends AbstractMchApiService<DgpayIsvParams> {

    @Autowired
    private ConfigContextQueryService configContextQueryService;

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

    @Override
    public boolean preCheck() {
        return true;
    }

    /**
     *
     * @param applyment
     * @param mchRq
     * 01-标准费率线上（支持统一进件页面版）
     * 02-标准费率线下（支持统一进件页面版）
     * 03-非盈利行业费率
     * 04-缴费行业费率
     * 05-保险行汪费率
     * 06-行业（蓝海绿洲）活动场景费率
     * 07-校园餐饮费率
     * 08-K12中小幼费率
     * 09-非在线教培行业费率
     * @return
     */
    @Override
    public ChannelRetMsg appidAndPath(MchApplyment applyment, ChannelMchRq mchRq) {
        JSONObject bizData = new JSONObject();
        bizData.put("req_seq_id", getIfCode() + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN));
        bizData.put("req_date", DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
        bizData.put("huifu_id",applyment.getChannelMchNo());
        if(ChannelMchRq.Type.PATH.getType().equals(mchRq.getType())){
            bizData.put("wx_woa_path",mchRq.getJsapiPath());
        }else if(ChannelMchRq.Type.PUBLIC.getType().equals(mchRq.getType())){
            bizData.put("wx_woa_app_id",mchRq.getAppid());
        }else if(ChannelMchRq.Type.APPLET.getType().equals(mchRq.getType())){
            bizData.put("wx_applet_app_id",mchRq.getAppid());
        }
        //默认写死  还不知道作用是什么 传线下
        bizData.put("fee_type","02");

        DgpayIsvParams isvParams = ((DgpayIsvParams) configContextQueryService.queryIsvParams(applyment));
        JSONObject respBizData = DgPayKit.req(DgPayKit.MCH_BUSI_CONFIG_URL, isvParams, bizData);
        ChannelRetMsg retMsg = new ChannelRetMsg();
        retMsg.setChannelBizData(respBizData);
        retMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
        return retMsg;
    }

    /**
     * 斗拱结算信息查询接口
     * @param settleRq
     * @param isvNo
     * @return
     */
    @Override
    public List<JSONObject> querySettleInfo(ChannelSettleRq settleRq, String isvNo, DgpayIsvParams isvParams) {
        if(StringUtils.isBlank(settleRq.getMercNo())){
            throw new BizException("缺失商户号");
        }
        JSONObject bizData = new JSONObject();
        bizData.put("req_seq_id",getIfCode() + DateUtil.format(new DateTime(),DatePattern.PURE_DATETIME_MS_FORMATTER));
        bizData.put("req_date",DateUtil.format(new DateTime(),DatePattern.PURE_DATE_PATTERN));
        bizData.put("huifu_id",settleRq.getMercNo());
        bizData.put("begin_date",DateUtil.format(settleRq.getStartDate(),DatePattern.PURE_DATE_PATTERN));
        bizData.put("end_date",DateUtil.format(settleRq.getEndDate(),DatePattern.PURE_DATE_PATTERN));
        bizData.put("page_num",settleRq.getPage());
        bizData.put("page_size",settleRq.getSize());
        JSONObject respBizData = DgPayKit.req(DgPayKit.MCH_BUSI_SETTLE_QUERY_URL, isvParams, bizData);
        JSONArray infos = respBizData.getJSONArray("trans_log_result_list");
        if(infos == null || infos.isEmpty()){
            return null;
        }
        List<JSONObject> result = new ArrayList<>(infos.size());
        infos.forEach(item -> {
            JSONObject itemData = ((JSONObject) item);
            JSONObject stlData = new JSONObject();
            stlData.put("billNo",itemData.getString("trans_id"));
            stlData.put("isvNo", isvNo);
            stlData.put("settleDate",DateUtil.format(DateUtil.parse(itemData.getString("trans_date"),DatePattern.PURE_DATE_PATTERN),DatePattern.NORM_DATE_PATTERN));
            stlData.put("accountNo",itemData.getString("card_no"));
            stlData.put("accountName",itemData.getString("card_name"));
            stlData.put("settleAmt",itemData.getBigDecimal("trans_amt").multiply(BigDecimal.valueOf(100)).longValue());
//            long feeAmt = itemData.getBigDecimal("fee_amt").multiply(BigDecimal.valueOf(100)).longValue();
//            if( feeAmt > 0L){
//                stlData.put("fee",feeAmt);
//            }
            stlData.put("remark",itemData.getString("settle_desc"));
            SettleState val = SettleState.getVal(itemData.getString("trans_stat"));
            switch (val){
                case PAY_SUCCESS:
                    stlData.put("state", SettleInfo.SUCCESS);
                    break;
                case PAY_FAIL:
                    stlData.put("state", SettleInfo.FAIL);
                    break;
                case PAY_PROGRESS:
                    stlData.put("state", SettleInfo.PROGRESS);
                    break;
            }
            stlData.put("channelState",val.getState());
            result.add(stlData);
        });
        return result;
    }

    @Getter
    @AllArgsConstructor
    public enum SettleState{

        PAY_PROGRESS("I","付款中"),

        PAY_SUCCESS("S","付款成功"),

        PAY_FAIL("F","付款失败");

        private final String state;

        private final String desc;

        public static SettleState getVal(String state){
            SettleState[] values = values();
            for (SettleState val:values) {
                if(val.getState().equals(state)){
                    return val;
                }
            }
            return PAY_PROGRESS;
        }
    }

}
