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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.entity.MchSubInfo;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.IIsvmchAlipayConfigService;
import com.jeequan.jeepay.core.model.applyment.ApplymentSignInfo;
import com.jeequan.jeepay.core.model.applyment.DgpayApplymentInfo;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.dgpay.DgpayIsvParams;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchSubInfoEntity;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchSubInfoService;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;

@Service
@Slf4j
public class DgpayIsvmchAlipayConfigService implements IIsvmchAlipayConfigService {

    @Autowired
    private MchSubInfoService mchSubInfoService;

    @Autowired
    private MchApplymentService mchApplymentService;

    @Autowired
    private MchInfoConverter mchInfoConverter;

    private void realNameApply(MchApplyment mchApplyment, DgpayIsvParams isvParams) {
        DgpayApplymentInfo applymentInfo = JSON.parseObject(mchApplyment.getApplyDetailInfo(), DgpayApplymentInfo.class);

        JSONObject suJson = JSON.parseObject(mchApplyment.getSuccResParameter());
        JSONObject reqParams = new JSONObject();
        // 汇付ID
        reqParams.put("huifu_id", suJson.getString("huifuId"));
        // 请求日期
        reqParams.put("req_date", DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
        // 请求流水号
        reqParams.put("req_seq_id", DateKit.currentTimeMillis() + "");

        reqParams.put("pay_scene", "1");

        // 主体信息
        JSONObject authIdentityInfo = new JSONObject();
        reqParams.put("auth_identity_info", authIdentityInfo);
        authIdentityInfo.put("business_type", getBusinessType(mchApplyment.getMerchantType()));
        authIdentityInfo.put("finance_institution_flag", "N");

        if (mchApplyment.getMerchantType() == MchApplyment.MERCHANT_TYPE_PERSONAL) {
            JSONObject supportCredentials = new JSONObject();
            authIdentityInfo.put("support_credentials", supportCredentials);
            supportCredentials.put("micro_biz_type", applymentInfo.getMicroBizType());
            supportCredentials.put("store_name", applymentInfo.getMchShortName());
            supportCredentials.put("province_code", applymentInfo.getAreaCode().getString(0));
            if (applymentInfo.getAreaName() != null) {
                supportCredentials.put("province", applymentInfo.getAreaName().getString(0));
            }
            supportCredentials.put("city_code", applymentInfo.getAreaCode().getString(1));
            if (applymentInfo.getAreaName() != null) {
                supportCredentials.put("city", applymentInfo.getAreaName().getString(1));
            }
            supportCredentials.put("district_code", applymentInfo.getAreaCode().getString(2));
            if (applymentInfo.getAreaName() != null) {
                supportCredentials.put("district", applymentInfo.getAreaName().getString(2));
            }

            if (applymentInfo.getMicroBizType().equals("MICRO_TYPE_MOBILE")) {
                supportCredentials.put("store_address", "无");
            } else {
                supportCredentials.put("store_address", applymentInfo.getAddress());
            }

            String f49 = DgPayKit.uploadFile(mchApplyment.getIsvNo(), "F49", applymentInfo.getStoreOuterImg(), mchApplyment.getIfCode());
            supportCredentials.put("store_door_img", f49);

            String f50 = DgPayKit.uploadFile(mchApplyment.getIsvNo(), "F50", applymentInfo.getStoreInnerImg(), mchApplyment.getIfCode());
            supportCredentials.put("store_inner_img", f50);
        } else {
            authIdentityInfo.put("certificate_type", "BUSINESS_CERT");

            JSONObject certificateInfo = new JSONObject();
            authIdentityInfo.put("certificate_info", certificateInfo);
            certificateInfo.put("cert_number", applymentInfo.getLicenseNo());
            String f07 = DgPayKit.uploadFile(mchApplyment.getIsvNo(), "F07", applymentInfo.getLicenseImg(), mchApplyment.getIfCode());
            certificateInfo.put("cert_copy", f07);
            certificateInfo.put("cert_merchant_name", applymentInfo.getMchFullName());
            certificateInfo.put("cert_legal_person", applymentInfo.getIdcardName());
            certificateInfo.put("cert_company_address", applymentInfo.getLicenseAddress());
            certificateInfo.put("effect_time", applymentInfo.getLicenseEffectBegin().replace("-", ""));
            certificateInfo.put("expire_time", applymentInfo.getLicenseEffectEnd().replace("-", ""));
        }

        JSONObject contactPersonInfo = new JSONObject();
        reqParams.put("contact_person_info", contactPersonInfo);
        contactPersonInfo.put("id_card_number", applymentInfo.getContactIdcardNo());

        MchAppConfigContext mchAppConfigContext = new MchAppConfigContext();
        mchAppConfigContext.setMchType(MchInfo.TYPE_ISVSUB);
        mchAppConfigContext.setMchApplyment(mchApplyment);

        JSONObject response = DgPayKit.request(mchAppConfigContext, reqParams, "/merchant/busi/ali/realname/apply", mchApplyment.getIfCode())
                .getJSONObject("data");

        if (!DgPayKit.STATE_SUCCESS.equals(response.getString("resp_code"))) {
            throw new BizException(response.getString("resp_desc"));
        }

        String applymentId = response.getString("applyment_id");
        String orderStatus = response.getString("order_status");

        if (orderStatus.equals("AUDITING")) {
            suJson.put("zfb_applyment_id", applymentId);
        }
        mchApplyment.setSuccResParameter(suJson.toJSONString());
        mchApplymentService.updateById(mchInfoConverter.toDbEntity(mchApplyment));
    }

    private String getBusinessType(Byte merchantType) {
        if (merchantType == MchApplyment.MERCHANT_TYPE_PERSONAL) {
            return "0";
        }

        if (merchantType == MchApplyment.MERCHANT_TYPE_INDIVIDUAL) {
            return "5";
        }

        if (merchantType == MchApplyment.MERCHANT_TYPE_ENTERPRISE) {
            return "3";
        }

        throw new BizException("无法判定的其他主体类型");
    }

    @Override
    public ApplymentSignInfo alipayOpenSignInfo(MchApplyment mchApplyment) {

        // 服务商配置参数
        ConfigContextQueryService configContextQueryService = SpringBeansUtil.getBean(ConfigContextQueryService.class);
        DgpayIsvParams isvParams = (DgpayIsvParams) configContextQueryService.queryIsvParams(mchApplyment.getIsvNo(), mchApplyment.getIfCode());

        ApplymentSignInfo result = new ApplymentSignInfo();

        // 进件商户信息
        JSONObject suJson = JSON.parseObject(mchApplyment.getSuccResParameter());
        if (suJson == null || StringUtils.isEmpty(suJson.getString("huifuId"))) {
            result.setState("查询失败");
            result.setErrInfo("商户参数为空，该商户还未进件成功");
            return result;
        }

        MchAppConfigContext mchAppConfigContext = new MchAppConfigContext();
        mchAppConfigContext.setMchType(MchInfo.TYPE_ISVSUB);
        mchAppConfigContext.setMchApplyment(mchApplyment);

        JSONObject reqParams = new JSONObject();
        // 汇付ID
        reqParams.put("huifu_id", suJson.getString("huifuId"));
        // 请求日期
        reqParams.put("req_date", DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
        // 请求流水号
        reqParams.put("req_seq_id", DateKit.currentTimeMillis() + "");

        // 发送请求
        JSONObject response = DgPayKit.request(mchAppConfigContext, reqParams, "/merchant/busi/realname/query", mchApplyment.getIfCode())
                .getJSONObject("data");

        // 请求流水号
        reqParams.put("req_seq_id", DateKit.currentTimeMillis() + "_info");
        // 商户详情is_open_small_flag -> 0
        JSONObject mchInfo = DgPayKit.request(mchAppConfigContext, reqParams, "/merchant/basicdata/query", mchApplyment.getIfCode());
        JSONObject mchInfoData = mchInfo.getJSONObject("data");
        String feeConfig = "";
        JSONArray wxConfList = mchInfoData.getJSONArray("qry_wx_conf_list");
        JSONArray aliConfList = mchInfoData.getJSONArray("qry_ali_conf_list");
        JSONObject unionConf = mchInfoData.getJSONObject("qry_union_conf");
        JSONObject bankCardConf = mchInfoData.getJSONObject("qry_bank_card_conf");

        for (int aliIndex = 0; aliIndex < aliConfList.size(); aliIndex++) {
            JSONArray aliMerInfos = aliConfList.getJSONObject(aliIndex).getJSONArray("ali_mer_infos");

            if (!CollUtil.isEmpty(aliMerInfos)) {

                for (int i = 0; i < aliMerInfos.size(); i++) {
                    JSONObject item = aliMerInfos.getJSONObject(i);
                    // 支付宝子商户号存在时
                    MchSubInfoEntity zfbSubInfo = new MchSubInfoEntity();
                    zfbSubInfo.setMchApplyId(mchApplyment.getApplyId());

                    String payChannelId = item.getString("pay_channel_id");
                    String bankMerCode = item.getString("bank_mer_code");
                    if (Objects.equals(isvParams.getChannelNo(), payChannelId)) {
                        zfbSubInfo.setMainUse(1);
                        result.setChannelSubMchId(bankMerCode);
                    } else {
                        zfbSubInfo.setMainUse(0);
                    }
                    zfbSubInfo.setSubMchWay("DG");
                    zfbSubInfo.setChannelMchNo(mchApplyment.getChannelMchNo());
                    zfbSubInfo.setChannelId(payChannelId);
                    zfbSubInfo.setAuthStatus(MchSubInfo.AUTH_STATUS_UNAUTHORIZED);
                    zfbSubInfo.setSubMchId(bankMerCode);
                    zfbSubInfo.setSubMchType("ZFB");
                    // 此处取1为正常
                    zfbSubInfo.setStatus("1");
                    zfbSubInfo.setExt(item);

                    try {
                        mchSubInfoService.save(zfbSubInfo);
                    } catch (DuplicateKeyException e) {
                        log.info("子商户信息已存储过");
                    }
                }
            }
        }


        // 支付宝申请单编号
//        String applymentId = suJson.getString("zfb_applyment_id");
//        if (applymentId == null) {
//            realNameApply(mchApplyment, isvParams);
//        }

        reqParams = new JSONObject();
        // 汇付ID
        reqParams.put("huifu_id", suJson.getString("huifuId"));
        // 请求日期
        reqParams.put("req_date", DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
        // 请求流水号
        reqParams.put("req_seq_id", DateKit.currentTimeMillis() + "");
//        reqParams.put("pay_channel_id", DateKit.currentTimeMillis()+"");
//        reqParams.put("pay_scene", "1");

        // 发送请求
        JSONObject response2 = DgPayKit.request(mchAppConfigContext, reqParams, "/merchant/busi/ali/realname/query", mchApplyment.getIfCode())
                .getJSONObject("data");

        String respCode = response2.getString("resp_code");
        String respDesc = response2.getString("resp_desc");

        if (!respCode.equals("00000000")) {
            result.setState("获取子商户状态异常");
            result.setErrInfo("【" + respDesc + "】");
            result.setImgType("qrContent");
            result.setSignUrl(isvParams.getAliChannelExtUrl());
            return result;
        }

        String orderStatus = response2.getString("order_status");
        if ("AUDITING".equals(orderStatus)) {
            result.setState("审核中");
        } else if ("CONTACT_CONFIRM".equals(orderStatus)) {
            result.setState("待联系人确认（扫码确认授权）");
            result.setImgType("imgUrl");
            result.setSignUrl(response2.getString("qrcode"));
        } else if ("LEGAL_CONFIRM".equals(orderStatus)) {
            result.setState("待法人确认（扫码确认授权）");
            result.setImgType("imgUrl");
            result.setSignUrl(response2.getString("qrcode"));
        } else if ("AUDIT_PASS".equals(orderStatus)) {
            result.setState("审核通过");
        } else if ("AUDIT_REJECT".equals(orderStatus)) {
            result.setState("审核失败");
        } else if ("AUDIT_FREEZE".equals(orderStatus)) {
            result.setState("已冻结（扫码确认授权）");
            result.setImgType("imgUrl");
            result.setSignUrl(response2.getString("qrcode"));
        } else if ("CANCELED".equals(orderStatus)) {
            result.setState("已撤回");
        } else if ("NOT_APPLY".equals(orderStatus)) {
            result.setState("未申请");
        }

        String authorizeStat = response2.getString("authorize_stat");

        LambdaUpdateChainWrapper<MchSubInfoEntity> stateUpdate = mchSubInfoService.lambdaUpdate()
                .eq(MchSubInfoEntity::getMchApplyId, mchApplyment.getApplyId())
                .eq(MchSubInfoEntity::getMainUse, 1)
                .eq(MchSubInfoEntity::getSubMchType, "ZFB");

        if ("AUTHORIZED".equals(authorizeStat)) {
            stateUpdate.set(MchSubInfoEntity::getAuthStatus, MchSubInfo.AUTH_STATUS_AUTHORIZED).update();
            result.setState("已授权");
        } else if ("UNAUTHORIZED".equals(authorizeStat)) {
            stateUpdate.set(MchSubInfoEntity::getAuthStatus, MchSubInfo.AUTH_STATUS_UNAUTHORIZED).update();
            result.setState("未授权");
        } else if ("CLOSED".equals(authorizeStat)) {
            result.setState("已销户");
        } else {
            result.setState("未报备");
        }


        if (ObjUtil.isEmpty(result.getSignUrl())) {
            // 渠道拓展地址
            result.setImgType("qrContent");
            result.setSignUrl(isvParams.getAliChannelExtUrl());
        }

        return result;
    }

}
