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


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.exception.BizException;
import lombok.Data;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.List;

@Data
public class RyxpayApplymentInfo extends ApplymentBasicInfo {

    /**
     * 商户类型
     * 00:聚合(默认) ，01 pos+聚合
     */
    private String merchType;

    private String posMerId;

    /**
     * 入网方式
     */
    private String accessMode;

    /**
     * 机构号
     */
    private String orgId;

    @JSONField(serialize = false)
    public String getMerProp() {
        if (merchantType.equals(MchApplyment.MERCHANT_TYPE_PERSONAL)) {
            return "7";
        }

        if (merchantType.equals(MchApplyment.MERCHANT_TYPE_INDIVIDUAL)) {
            return "1";
        }

        if (merchantType.equals(MchApplyment.MERCHANT_TYPE_ENTERPRISE)) {
            return "2";
        }

        throw new BizException("未知的商户类型");
    }

    /**
     * 商户简称
     * merProp=7时，不传
     * 用于银联银行卡交易报送，商户POS签购单打印名称等场景
     */
    @JSONField(serialize = false)
    public String getMerName() {
        return mchShortName;
    }

    /**
     * 商户营业执照上的名称，
     * 用于向支付宝和微信进行报备和实名认证（经营证件类型为营业执照时，不需要传）
     */
    @JSONField(serialize = false)
    public String getOrgMerName() {
        return mchFullName;
    }

    /**
     * 经营名称
     * 扫码交易时，收款成功页面展示的名称
     */
    @JSONField(serialize = false)
    public String getMerNameAbbr() {
        return mchShortName;
    }

    /**
     * 【商户性质】为“个体“、”企业“、”其他”、“党政、机关及事业单位”时，需要传该字段。
     * 00：普通，商户与商户没有关系
     * 01：连锁，可以使用统一营业执照，也可以使用自己的营业执照
     * 02：市场，多商户使用同一营业执照
     */
    private String merchRelp;

    /**
     * 经营证件类型小微商户不传
     * 参考：商户性质与经营证件类型对应关系
     * 1, 营业执照
     */
    private String licType;

    /**
     * 使用 licenseNo
     * 经营证件号码
     * 小微商户不传
     */
    @JSONField(serialize = false)
    public String getLicNum() {
        return licenseNo;
    }

    /**
     * 经营证件有效期开始时间，使用 licenseEffectBegin
     * 小微商户不传
     * 格式yyyyMMdd
     */
    @JSONField(serialize = false)
    public String getLicNumStartTime() {
        Assert.notNull(licenseEffectBegin, "经营证件有效期开始时间不能为空");
        return licenseEffectBegin.replace("-", "");
    }

    /**
     * 使用 licenseEffectEnd
     * 经营证件有效期结束日期
     * 小微商户不传
     * 格式yyyyMMdd,长期传空
     */
    @JSONField(serialize = false)
    public String getLicNumTime() {
        Assert.notNull(licenseEffectEnd, "经营证件有效期截止时间不能为空");
        if ("长期".equals(licenseEffectEnd)) {
            return "";
        }

        return licenseEffectBegin.replace("-", "");
    }

    /**
     * 法人姓名, 小微商户不传
     * 需要与营业执照上的法人名称一致
     */
    @JSONField(serialize = false)
    public String getCredPeople() {
        return idcardName;
    }

    /**
     * 法人证件类型
     * 小微商户不传
     * 0105：身份证
     * 0202：护照
     * 0114：中国香港居民-来往内地通行证
     * 0115: 中国澳门居民-来往内地通行证
     * 0116: 中国台湾居民-来往大陆通行证
     * 0558：港澳居住证
     * 0557：台湾居住证
     * 0559：外国人永久居留证
     */
    @JSONField(serialize = false)
    public String getCredType() {
        return "0105";
    }

    /**
     * 法人证件号
     * 小微商户不传
     */
    @JSONField(serialize = false)
    public String getCredNo() {
        return idcardNo;
    }

    /**
     * 法人证件有效期开始时间
     * 小微商户不传
     */
    @JSONField(serialize = false)
    public String getCredStartTime() {
        Assert.notNull(idcardEffectBegin, "法人身份证有效期开始时间不能为空");
        return idcardEffectBegin.replace("-", "");
    }

    /**
     * 法人证件有效期截止时间
     * 小微商户不传
     */
    @JSONField(serialize = false)
    public String getCredTime() {
        Assert.notNull(idcardEffectEnd, "法人身份证有效期截止时间不能为空");
        if ("长期".equals(idcardEffectEnd)) {
            return "";
        }

        return idcardEffectEnd.replace("-", "");
    }

    /**
     * 商户入网县编码(银联码)
     */
    @JSONField(serialize = false)
    public String getCityArea() {
        if (areaCode == null || areaCode.size() < 3) {
            throw new BizException("缺少经营地区编码");
        }
        return areaCode.getString(2);
    }

    /**
     * 经度
     */
    private String longitude;

    /**
     * 纬度
     */
    private String latitude;

    /**
     * 经营地址省（国标码）
     */
    @JSONField(serialize = false)
    public String getOperateProvince() {
        if (areaCode == null || areaCode.isEmpty()) {
            throw new BizException("缺少经营地区编码");
        }
        return areaCode.getString(0);
    }

    ;

    /**
     * 经营地址市编码（国标码）
     */
    @JSONField(serialize = false)
    public String getOperateCity() {
        if (areaCode == null || areaCode.size() < 2) {
            throw new BizException("缺少经营地区编码");
        }
        return areaCode.getString(1);
    }

    /**
     * 经营地址区编码（国标码）
     */
    @JSONField(serialize = false)
    public String getOperateArea() {
        if (areaCode == null || areaCode.size() < 3) {
            throw new BizException("缺少经营地区编码");
        }
        return areaCode.getString(2);
    }

    /**
     * 联系人
     */
    @JSONField(serialize = false)
    public String getContactPerson() {
        return contactName;
    }

    @JSONField(serialize = false)
    public String getOperateAddr() {
        return address;
    }

    /**
     * 注册地址
     */
    @JSONField(serialize = false)
    public String getRegAddr() {
        return mchAddress;
    }

    /**
     * 经营范围
     */
    @JSONField(serialize = false)
    public String getManaScop() {
        return mccName;
    }

    @JSONField(serialize = false)
    public String getMcc() {
        return mccCode;
    }

    /**
     * 结算卡号
     */
    @JSONField(serialize = false)
    public String getBankCard() {
        return settAccountNo;
    }

    /**
     * 账户类型
     */
    @JSONField(serialize = false)
    public String getAccountProp() {
        if ("B".equals(settAccountType)) {
            return "00";
        }

        if ("C".equals(settAccountType)) {
            return "01";
        }

        throw new BizException("未知的账户类型");
    }

    /**
     * 结算类型
     * 1：法人，2：非法人，3：对公
     * 账户性质为‘对公’时，传‘3’，对私时，传‘1’或‘2’
     */
    @JSONField(serialize = false)
    public String getSettleType() {
        if ("B".equals(settAccountType)) {
            return "3";
        }

        if ("Y".equals(authSettle)) {
            return "2";
        } else {
            return "1";
        }
    }

    /**
     * 账户名
     */
    @JSONField(serialize = false)
    public String getBankCardName() {
        return settAccountName;
    }

    /**
     * 结算证件类型
     */
    @JSONField(serialize = false)
    public String getSettleCredType() {
        return "0105";
    }

    /**
     * 结算证件号码
     */
    @JSONField(serialize = false)
    public String getSettleCredNo() {
        if (getSettleType().equals("2")) {
            return settAccountIdcardNo;
        }

        return idcardNo;
    }

    /**
     * 结算证件号码
     */
    @JSONField(serialize = false)
    public String getSettleCredStartTime() {
        if (getSettleType().equals("2")) {
            Assert.notNull(settAccountIdcardEffectBegin, "缺少结算人证件的有效期开始时间");
            return settAccountIdcardEffectBegin.replace("-", "");
        }

        Assert.notNull(idcardEffectBegin, "缺少法人证件的有效期开始时间");
        return idcardEffectBegin.replace("-", "");
    }

    /**
     * 结算证件有效期结束日期
     * 格式yyyyMMdd,长期传空
     */
    @JSONField(serialize = false)
    public String getSettleCredTime() {
        if (getSettleType().equals("2")) {
            Assert.notNull(settAccountIdcardEffectEnd, "缺少结算人证件的有效期开始时间");
            if ("长期".equals(settAccountIdcardEffectEnd)) {
                return "";
            }

            return settAccountIdcardEffectEnd.replace("-", "");
        }

        Assert.notNull(idcardEffectEnd, "缺少法人证件的有效期开始时间");
        if ("长期".equals(idcardEffectEnd)) {
            return "";
        }

        return idcardEffectEnd.replace("-", "");
    }

    @JSONField(serialize = false)
    public String getBankCityArea() {
        if (settAccountBankBranchAreaCode == null || settAccountBankBranchAreaCode.size() < 3) {
            throw new BizException("缺少开户支行县区编码");
        }
        return settAccountBankBranchAreaCode.getString(2);
    }

    /**
     * 结算开户银行编码
     */
    @JSONField(serialize = false)
    public String getHeadBankNo() {
        return settAccountBankCode;
    }



    @JSONField(serialize = false)
    public String getOpenBankName() {
        return settAccountBankBranchName;
    }

    /**
     * 结算开户支行编码
     */
    @JSONField(serialize = false)
    public String getOpenBankChild() {
        return settAccountBankBranchCode;
    }

    /**
     * 是否启用标准费率
     * 1：是，2：否。默认传2
     */
    private String modelType;

    /**
     * 借记费率（%）
     * 银联二维码交易额大于1000
     */
    private String debitRate;

    /**
     * 借记封顶额(元)
     * 银联二维码交易额大于1000
     */
    private String debitTop;

    /**
     * 贷记费率（%）
     * 针对银联二维码交易额大于1000的该字段必填
     */
    private String creditRate;

    /**
     * 银联云闪付借记费率(%)
     * 数值, 银联二维码交易额小于等于1000
     */
    private String qrDebitRate;

    /**
     * 银联云闪付贷记费率(%)
     * 数值，银联二维码交易额小于等于1000
     */
    private String qrCreditRate;

    /**
     * 微信交易费率(%)
     */
    private String wxDebitRate;

    /**
     * 支付宝交易费率(%)
     */
    private String zfbDebitRate;

    private String remark;

    /**
     * 数值类型，小微商户最大20，普通商户最大9
     * 统一传1
     */
    private String termNum;

    /**
     * 结算业务类型
     * 01：T1,   第二个工作日 9点到11点
     * 02: S0,
     * 03: D1,   第二个自然日 9点到11点
     * 04：D1+   第二个自然日 8点30左右打款
     */
    @JSONField(serialize = false)
    public String getServiceType() {
        if (CS.SETTLEMENT_TYPE.D1.equals(settlementType)) {
            return "04";
        }

        if (CS.SETTLEMENT_TYPE.T1.equals(settlementType)) {
            return "01";
        }

        throw new BizException("未知的结算方式");
    }

    /**
     * 是否开通退款
     * 0：是，1：否
     */
    private String tradeTypeReimburse;

    /**
     * 是否进行微信实名认证
     */
    private String certificationType;

    /**
     * 是否进行支付宝实名认证
     */
    private String alipayCertificationType;

    /**
     * 店铺注册地址
     * 在【是否进行支付宝实名认证】选择了“是”，“企业/个体/党政机关及事业单位/其他”必传
     */
    private String regAddress;

    /**
     * 法人证件居住地址
     * “企业/个体/党政机关及事业单位/其他”必传
     */
    @JSONField(serialize = false)
    public String getCredAddr() {
        Assert.notNull(idcardAddress, "法人证件居住地址不能为空");
        return idcardAddress;
    }

    @JSONField(serialize = false)
    public String getContactSameToLegal() {
        if (contactIdcardNo == null) {
            return "1";
        }

        if (contactIdcardNo.equals(idcardNo)) {
            return "1";
        }

        return "0";
    }

    /**
     * 联系人证件类型
     * 0105：身份证
     * 0202：护照
     * 0114：中国香港居民-来往内地通行证
     * 0115: 中国澳门居民-来往内地通行证
     * 0116: 中国台湾居民-来往大陆通行证
     * 0558：港澳居住证
     * 0557：台湾居住证
     * 0559：外国人永久居留证
     */
    private String contactCredType;

    @JSONField(serialize = false)
    public String getContactStartTime() {
        if ("1".equals(getContactSameToLegal())) {
            return idcardEffectBegin.replace("-", "");
        }

        Assert.notNull(contactIdcardEffectBegin, "联系人证件有效期开始时间不能为空");
        return contactIdcardEffectBegin.replace("-", "");
    }

    @JSONField(serialize = false)
    public String getContactCardImg1() {
        if ("1".equals(getContactSameToLegal())) {
            return idcard1Img;
        }

        Assert.notNull(contactIdcard1Img, "联系人证件卡号面不能为空");
        return contactIdcard1Img;
    }

    @JSONField(serialize = false)
    public String getContactCardImg2() {
        if ("1".equals(getContactSameToLegal())) {
            return idcard2Img;
        }

        Assert.notNull(contactIdcard2Img, "联系人证件国徽面面不能为空");
        return contactIdcard2Img;
    }



    /**
     * 联系人证件有效期结束日期
     */
    @JSONField(serialize = false)
    public String getContactTime() {
        if ("1".equals(getContactSameToLegal())) {
            return idcardEffectEnd.replace("-", "");
        }

        Assert.notNull(contactIdcardEffectEnd, "联系人证件有效期开始时间不能为空");
        return contactIdcardEffectEnd.replace("-", "");
    }

    /**
     * 联系人身份证号
     */
    @JSONField(serialize = false)
    public String getContactPersonCred() {
        if ("1".equals(getContactSameToLegal())) {
            return idcardNo;
        }

        return contactIdcardNo;
    }

    /**
     * 经营类型
     * 开通微信实名认证，商户性质为‘市场‘或’连锁‘或‘小微商户‘时，必传。（certificationType=1，merPro=3|5|7）
     * 1:门店场所
     * 2: 流动经营/便民服务
     */
    private String microBizType;

    /**
     * 支付授权目录
     * 多条数据，用逗号分隔
     */
    private String jsapiPath;

    private String subAppid;

    /**
     * 商户协议类型
     * 0：纸质协议（默认）
     * 1：电子协议（需要开通权限）
     */
    private String pactType;

    // 受益人信息不填


    public void collRateInfo(JSONObject result) {
        paywayFeeList.forEach(item -> {
            // 线上费率
            if (CS.PAY_WAY_CODE.SCAN.equals(item.getWayCode())) {
                result.put("wxDebitRate", convertRate(item.getFeeRate()));
                result.put("zfbDebitRate", convertRate(item.getFeeRate()));

                result.put("qrDebitRate", convertRate(item.getFeeRate()));
                // 费率
                result.put("debitRate", convertRate(item.getFeeRate()));
                // 封顶
                result.put("debitTop", "20");
                result.put("qrCreditRate", convertRate(item.getFeeRate()));
                result.put("creditRate", convertRate(item.getFeeRate()));

                return;
            }

            // 微信费率
            if (item.getWayCode().startsWith("WX_")) {
                result.put("wxDebitRate", convertRate(item.getFeeRate()));
            }
            // 支付宝费率
            if (item.getWayCode().startsWith("ALI_")) {
                result.put("zfbDebitRate", convertRate(item.getFeeRate()));
            }

            // 云闪付费率
            if (item.getWayCode().startsWith("YSF_")) {
                List<PaywayFee> levelList = item.getLevelList();
                // 借记卡费率
                levelList.forEach(ysfItem -> {
                    if (ysfItem.getMaxFee() == 100000L) {
                        result.put("qrDebitRate", convertRate(ysfItem.getFeeRate()));
                    } else {
                        // 费率
                        result.put("debitRate", convertRate(ysfItem.getFeeRate()));
                        // 封顶
                        result.put("debitTop", "20");
                    }
                });

                // 贷记卡费率
                List<PaywayFee> creditLevelList = item.getCreditCardPaywayFee().getLevelList();
                creditLevelList.forEach(creditYsfItem -> {
                    if (creditYsfItem.getMaxFee() == 100000L) {
                        result.put("qrCreditRate", convertRate(creditYsfItem.getFeeRate()));
                    } else {
                        // 费率
                        result.put("creditRate", convertRate(creditYsfItem.getFeeRate()));
                    }
                });
            }
        });
    }

    private String convertRate(BigDecimal rate) {
        return rate.multiply(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString();
    }
}
