package com.jeequan.jeepay.core.model.applyment;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.model.params.epspay.EpspayIsvParams;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class EpspayApplymentInfo extends ApplymentBasicInfo {
    /** D1增值费用类型 0按笔 1按比例 **/
    public static final Byte HOLIDAY_TYPE_PER = 0;
    public static final Byte HOLIDAY_TYPE_RATE = 1;

    /** 结算周期常量  **/
    public static final String SETTLE_WAY_D0 = "D+0";
    public static final String SETTLE_WAY_D1 = "D+1";
    public static final String SETTLE_WAY_T0 = "T+0";
    public static final String SETTLE_WAY_T1 = "T+1";

    /** 证照商户名称 **/
    private String businessLicenseName;
    /** 经营范围 **/
    private String licenseBusiness;
    /** 注册地址  **/
    public String registerAddress;

    /**
     * 法人手机号码
     **/
    public String legalPersonPhone;

    /**
     * 微信经营类目
     **/
    public String wxMccCode;
    /**
     * 支付宝经营类目(支付宝-MCC)
     **/
    public String aliMccCode;

    /** 预留手机号 **/
    public String prePhone;

    /** 结算账户附件 **/
    public String settleAttachment;
    /** 客服电话 **/
    public String serviceTel;

    /** 是否已签约协议书 **/
    public String contractStatus;
    /** 协议书盖章页/签名页附件 **/
    public String contractAttachment;
    /** 转账功能开通申请书附件 **/
    public String transferApplyAttachment;

    /** 开户行联行号 **/
    public String openBankCode;
    /** 证明文件 **/
    public String openingLicenseAccountPhoto;

    /** 分账收单手续费类型 1-按平台商费率收取，2-按交易主体费率收取 **/
    public String splitOriTradeFee;

    /** 节假日垫资费率方式 0：按单笔收费；1：按比例收费；结算周期 D+1 时有效 **/
    public String holidayType;

    /** 节假日垫资费率方式 isv：使用服务商的配置 mch：给商户单独配置 **/
    public String holidayTypeConfig;

    /**
     * 注册资本 单位：元
     **/
    public Long registeredCapital;

    // 支付方式分类Code
    public static final Map<String, String> PAY_WAY_CODE_MAP = new HashMap<>();

    static {
        // 支付宝支付业务
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.ALI_JSAPI, "ALI_JSAPI_PAY");   // 支付宝生活号支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.ALI_LITE, "ALI_JSAPI_PAY");    // 支付宝小程序支付（实际上是：支付宝生活号支付）
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.ALI_BAR, "ALI_MICRO_PAY");     // 支付宝被扫支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.ALI_QR, "ALI_NATIVE_PAY");     // 支付宝主扫支付
        // 微信支付业务
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.WX_JSAPI, "WX_JSAPI_PAY");     // 微信公众号支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.WX_LITE, "WX_MINI_PROGRAM");   // 微信小程序支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.WX_BAR, "WX_MICRO_PAY");       // 微信被扫支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.WX_NATIVE, "WX_NATIVE_PAY");   // 微信主扫支付
        // 银联支付业务
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.UP_JSAPI, "UNION_JS");         // 银联二维码 JS 支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.YSF_JSAPI, "UNION_JS");        // 银联二维码 JS 支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.UP_BAR, "UNION_ONLINE");       // 银联二维码被扫支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.YSF_BAR, "UNION_ONLINE");      // 银联二维码被扫支付
        PAY_WAY_CODE_MAP.put(CS.PAY_WAY_CODE.UP_QR, "UNION_SWEEP");         // 银联二维码主扫支付
    }

    // 分账业务
    public static final String TRADE_SPLIT = "TRADE_SPLIT";         // 交易分账
    public static final String ACCOUNT_SPLIT = "ACCOUNT_SPLIT";     // 账户分账
    public static final String ORDER_SPLIT = "ORDER_SPLIT";         // 拆单分账

    // 提现&代付业务
    public static final String WITHDRAW = "WITHDRAW";                                   // 代付到储蓄卡
    public static final String WITHDRAW_CREDIT_CARD = "WITHDRAW_CREDIT_CARD";           // 代付到信用卡
    public static final String WITHDRAW_TO_SETTMENT_CREDIT = "WITHDRAW_TO_SETTMENT_CREDIT";         // 提现到信用卡
    public static final String WITHDRAW_TO_SETTMENT_DEBIT = "WITHDRAW_TO_SETTMENT_DEBIT";           // 提现到储蓄卡


    /**
     *  主体类型 1：个体工商户；2：企业；3：个人(小微)；4：政府事业单位；9：其他组织
     */
    public String convertMerchantType(){
        if(this.merchantType == MchApplyment.MERCHANT_TYPE_PERSONAL){
            return "3";
        }else if(this.merchantType == MchApplyment.MERCHANT_TYPE_INDIVIDUAL){
            return "1";
        }else if(this.merchantType == MchApplyment.MERCHANT_TYPE_ENTERPRISE){
            return "2";
        }
        return "";
    }

    // 有效期转换
    public String coverDateTime(String dateStr) {
        if ("长期".equals(dateStr)) {
            return dateStr;
        } else {
            return dateStr.replace("-", "");
        }
    }


    /** 结算账户类型  1：对公账户 2：法人账户 3：授权对公 4：授权对私 **/
    public String convertAccountType() {
        if (MchApplyment.SETT_ACCOUNT_TYPE_CORPORATE.equals(this.getSettAccountType())) {
            return "1";
        }else if ("B2".equals(this.getSettAccountType())) {
            return "3";
        }else if (MchApplyment.SETT_ACCOUNT_TYPE_PERSONAL.equals(this.getSettAccountType())) {
            return "2";
        }else if ("C2".equals(this.getSettAccountType())) {
            return "4";
        }
        return "";
    }

    /**
     * 收单类商户使用，费率相关业务信息
     **/
    public List<JSONObject> convertApplymentPayFee(EpspayIsvParams epspayIsvParams) {
        // 业务信息集合，使用map为了去重
        Map<String, JSONObject> businessListMap = new HashMap<>();
        List<PaywayFee> paywayFeeList = this.paywayFeeList;
        // 费率设置列表
        if (paywayFeeList != null && CollectionUtils.isNotEmpty(paywayFeeList)) {
            paywayFeeList.stream().forEach(item -> {
                if (PaywayFee.FEE_TYPE_SINGLE.equals(item.getFeeType())) {
                    // 业务代码
                    rateJson(CS.YES, businessListMap, epspayIsvParams, PAY_WAY_CODE_MAP.get(item.getWayCode()), null, convertRate(item.getFeeRate()), null, null);
                }

                // 阶梯费率(文档中没有明确划分借贷记，暂按借记卡取值
                if ((item.getWayCode().startsWith("YSF_") || item.getWayCode().startsWith("UP_")) && PaywayFee.FEE_TYPE_LEVEL.equals(item.getFeeType())) {
                    // 借记卡费率
                    if (CollUtil.isNotEmpty(item.getLevelList())) {
                        rateJson(CS.YES, businessListMap, epspayIsvParams, PAY_WAY_CODE_MAP.get(item.getWayCode()), item.getMinFee(), convertRate(item.getLevelList().get(0).getFeeRate()), item.getMaxFee(), convertRate(item.getLevelList().get(1).getFeeRate()));
                    }
                    // 贷记卡费率
//                    if (item.getCreditCardPaywayFee() != null && CollUtil.isNotEmpty(item.getCreditCardPaywayFee().getLevelList())) {
//                        rateList(businessList, epspayIsvParams, PAY_WAY_CODE_MAP.get(item.getWayCode()), item.getCreditCardPaywayFee().getMinFee(), convertRate(item.getCreditCardPaywayFee().getLevelList().get(0).getFeeRate()), item.getCreditCardPaywayFee().getMaxFee(), convertRate(item.getCreditCardPaywayFee().getLevelList().get(1).getFeeRate()));
//                    }
                }
            });
        }
        // 交易分账
        rateJson(CS.NO, businessListMap, epspayIsvParams, TRADE_SPLIT, null, 0L, null, null);

        // 提现&代付业务
        rateJson(CS.NO, businessListMap, epspayIsvParams, WITHDRAW, null, 0L, null, null);
        rateJson(CS.NO, businessListMap, epspayIsvParams, WITHDRAW_TO_SETTMENT_DEBIT, null, 0L, null, null);

        return new ArrayList<>(businessListMap.values());
    }

    /**
     * 非收单类商户使用，提现信息
     **/
    public List<JSONObject> convertApplymentPaySplit(EpspayIsvParams epspayIsvParams) {
        // 业务信息集合，使用map为了去重
        Map<String, JSONObject> businessListMap = new HashMap<>();
        // 提现&代付业务
        rateJson(CS.NO, businessListMap, epspayIsvParams, WITHDRAW, null, 0L, null, null);
        rateJson(CS.NO, businessListMap, epspayIsvParams, WITHDRAW_TO_SETTMENT_DEBIT, null, 0L, null, null);

        return new ArrayList<>(businessListMap.values());
    }

    /** 费率转换 **/
    public static Long convertRate(BigDecimal rate) {
        return rate == null ? null : Long.valueOf(String.valueOf(rate.multiply(new BigDecimal(10000)).setScale(0, BigDecimal.ROUND_HALF_UP)));
    }

    /** 将服务商填写的D1附加费率或单笔手续费*100 **/
    public static Long convertStrToLong(String str) {
        if (StringUtils.isNotEmpty(str)) {
            return new BigDecimal(str).multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
        }
        return null;
    }

    /**
     * 业务申请信息：business  模式 ifRate 1 比例  0单笔
     */
    private void rateJson(Byte ifRate, Map<String, JSONObject> businessListMap, EpspayIsvParams epspayIsvParams, String businessCode, Long feeMin, Long minRate, Long feeMax, Long maxRate) {
        if (businessCode == null) {
            return;
        }
        JSONObject businessJson = new JSONObject();
        // 业务代码
        businessJson.put("businessCode", businessCode);
        // 手续费费率
        businessJson.put("stage", setStageList(ifRate, minRate, maxRate));
        // 保底手续费 LONG 默认无保底手续费
        if (feeMin != null) {
            businessJson.put("feeMin", feeMin);
        }

        // 封顶手续费 默认上不封顶
        if (feeMax != null) {
            businessJson.put("feeMax", feeMax);
        }

        // 允许退款 0：不允许；1：允许
        businessJson.put("refundEnabled", "1");
        // 是否允许信用卡支付 0:禁用，1：允许；默认 0
        businessJson.put("creditcardsEnabled", "1");

        // 结算周期
        businessJson.put("settleCycle", epspayIsvParams.getSettleWay());
        // 分账收单手续费类型 1-按平台商费率收取，2-按交易主体费率收取 非必填
//        businessJson.put("splitOriTradeFee", "");
        if (epspayIsvParams.getSettleWay().equals(SETTLE_WAY_D1)) {
            // 节假日垫资费率方式 0：按单笔收费；1：按比例收费；结算周期 D+1 时有效
            businessJson.put("holidayType", epspayIsvParams.getHolidayType());
            if (epspayIsvParams.getHolidayType().equals(HOLIDAY_TYPE_PER)) {
                // D1 交易节假日附加收费的单笔加收费用  单位为分. 比如 3 表示 3 分。结算周期 D+1 时有效，与holidayRate 二选一
                businessJson.put("holidayPer", convertStrToLong(epspayIsvParams.getHolidayPer()));
            } else if (epspayIsvParams.getHolidayType().equals(HOLIDAY_TYPE_RATE)) {
                // D1 交易节假日附加收费的费率  万份比.比如值为 200,表示万分之200,即百二。结算周期 D+1 时有效，与 holidayPer 二选一
                businessJson.put("holidayRate", convertStrToLong(epspayIsvParams.getHolidayRate()));
            }
        }
        businessListMap.put(businessCode, businessJson);
    }

    /**
     * 业务申请信息：business
     */
    private List setStageList(Byte ifRate, Long minRate, Long maxRate) {
        List<JSONObject> stageList = new ArrayList<>();
        JSONObject stageJson = new JSONObject();
        if (ifRate == CS.YES) {
            // 按比例收费 根据交易金额的比率收费, 单位”万分比”.例:万二三的费率,传 23 即可
            stageJson.put("feeRate", minRate);
        } else {
            // 单笔交易计费，单位”分/笔”。feeRate 与 feePer 都传即为混合计费
            stageJson.put("feePer", 0);
        }
        // 阶梯起始交易金额 默认 0，闭区间，满足条件：交易金额>amountFrom AND 交易额 <= 下一阶梯的 amountFrom
        stageJson.put("amountFrom", 0);

        stageList.add(stageJson);
        if (maxRate != null) {
            JSONObject stageMaxJson = new JSONObject();
            // 按比例收费 根据交易金额的比率收费, 单位”万分比”.例:万二三的费率,传 23 即可
            stageMaxJson.put("feeRate", maxRate);
            // 阶梯起始交易金额 默认 0，闭区间，满足条件：交易金额>amountFrom AND 交易额 <= 下一阶梯的 amountFrom
            stageMaxJson.put("amountFrom", 1000);
            stageList.add(stageMaxJson);
        }
        return stageList;
    }

    /**
     * MCC
     **/
    public String coverMcc(String mccCode) {
        if (StringUtils.isNotEmpty(mccCode)) {
            String[] split = mccCode.split("_");
            return split[1];
        }
        return null;
    }

    @Override
    public String bankBranchNo() {
        return openBankCode;
    }
}
