package com.hfkj.channel.weixin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hfkj.channel.weixin.utils.HttpClientBuilder;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.entity.*;
import com.hfkj.model.MerBasisModel;
import com.hfkj.model.StoreModel;
import com.hfkj.service.*;
import com.hfkj.sysenum.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @className: WeixinMerService
 * @author: HuRui
 * @date: 2022/11/15
 **/
@Service("weiXinMerService")
public class WeiXinMerService {

    @Resource
    private BsMerService merService;

    @Resource
    private BsMerAttachService merAttachService;

    @Resource
    private BsMerContractRecordService merContractRecordService;

    @Resource
    private BsStoreService storeService;

    @Resource
    private BsStoreAttachService storeAttachService;

    @Resource
    private BsStoreContractRecordService storeContractRecordService;

    @Resource
    private BsIndustryService industryService;

    private List<BsMerAttach> merAttachList;

    private List<BsStoreAttach> storeAttachList;

    /**
     * 商户进件
     * @param merId
     */
    public void addMer(Long merId) throws Exception {
        MerBasisModel basisModel = merService.getMerDetail(merId);

        // 查询商户附件列表
        merAttachList = merAttachService.getAttachListByMer(merId, PlatformTypeEnum.type0, null);

        JSONObject body = new JSONObject();
        body.put("business_code", ""+merId+""+System.currentTimeMillis());

        // 超级管理员
        JSONObject contactInfo = new JSONObject();
        contactInfo.put("contact_type", "LEGAL");
        contactInfo.put("contact_name", HttpClientBuilder.rsaEncryptOAEP(basisModel.getRegName()));
        contactInfo.put("contact_email", HttpClientBuilder.rsaEncryptOAEP(basisModel.getRegEmail()));
        contactInfo.put("mobile_phone", HttpClientBuilder.rsaEncryptOAEP(basisModel.getRegPhone()));
        body.put("contact_info", contactInfo);

        // 主体资料
        JSONObject 	subjectInfo = new JSONObject();
        subjectInfo.put("subject_type", MerTypeEnum.getDataByNumber(basisModel.getMerType()).getWxCode());

        // 营业执照
        JSONObject businessLicenseInfo = new JSONObject();
        businessLicenseInfo.put("license_copy", getMerAttach(MerAttachType.type1,true).get(0).getFileUrl());
        businessLicenseInfo.put("license_number", basisModel.getBlisNo());
        businessLicenseInfo.put("merchant_name", basisModel.getBlisName());
        businessLicenseInfo.put("legal_person", basisModel.getLarName());
        businessLicenseInfo.put("license_address", basisModel.getBlisRegAddress());
        businessLicenseInfo.put("period_begin", basisModel.getBlisPeriodStart().replace("年", "-").replace("月", "-").replace("日", ""));
        if (basisModel.getBlisPeriodType().equals(2)) {
            businessLicenseInfo.put("period_end", "长期");
        } else {
            businessLicenseInfo.put("period_end", basisModel.getBlisPeriodEnd().replace(".", "-"));
        }
        subjectInfo.put("business_license_info", businessLicenseInfo);

        // 经营者/法人身份证件
        JSONObject identityInfo = new JSONObject();
        identityInfo.put("id_holder_type", "LEGAL");
        identityInfo.put("id_doc_type", "IDENTIFICATION_TYPE_IDCARD");

        if (basisModel.getMerType().equals(MerTypeEnum.status2.getNumber())) {
            identityInfo.put("owner", true);
        }

        // 当证件持有人类型为经营者/法人且证件类型为“身份证”时填写。
        JSONObject idCardInfo = new JSONObject();
        idCardInfo.put("id_card_copy", getMerAttach(MerAttachType.type2,true).get(0).getFileUrl());
        idCardInfo.put("id_card_national", getMerAttach(MerAttachType.type3,true).get(0).getFileUrl());
        idCardInfo.put("id_card_name", HttpClientBuilder.rsaEncryptOAEP(basisModel.getLarName()));
        idCardInfo.put("id_card_number", HttpClientBuilder.rsaEncryptOAEP(basisModel.getLarIdCard()));
        idCardInfo.put("id_card_address", HttpClientBuilder.rsaEncryptOAEP(basisModel.getLarIdCardAddress()));
        idCardInfo.put("card_period_begin", basisModel.getLarIdCardPeriodStart().replace(".", "-"));
        if (basisModel.getLarIdCardPeriodType().equals(2)) {
            idCardInfo.put("card_period_end", "长期");
        } else {
            idCardInfo.put("card_period_end", basisModel.getLarIdCardPeriodEnd().replace(".", "-"));
        }
        identityInfo.put("id_card_info", idCardInfo);
        subjectInfo.put("identity_info", identityInfo);

        // 企业才需要填写受益人
        if (basisModel.getMerType().equals(MerTypeEnum.status2.getNumber())) {
            JSONArray uboInfoList = new JSONArray();
            JSONObject uboInfo = new JSONObject();
            uboInfo.put("ubo_id_doc_type", "IDENTIFICATION_TYPE_IDCARD");
            uboInfo.put("ubo_id_doc_copy", getMerAttach(MerAttachType.type2,true).get(0).getFileUrl());
            uboInfo.put("ubo_id_doc_copy_back", getMerAttach(MerAttachType.type3,true).get(0).getFileUrl());
            uboInfo.put("ubo_id_doc_name", HttpClientBuilder.rsaEncryptOAEP(basisModel.getLarName()));
            uboInfo.put("ubo_id_doc_number", HttpClientBuilder.rsaEncryptOAEP(basisModel.getLarIdCard()));
            uboInfo.put("ubo_id_doc_address", HttpClientBuilder.rsaEncryptOAEP(basisModel.getLarIdCardAddress()));
            uboInfo.put("ubo_period_begin", basisModel.getLarIdCardPeriodStart().replace(".", "-"));
            if (basisModel.getLarIdCardPeriodType().equals(2)) {
                uboInfo.put("ubo_period_end", "长期");
            } else {
                uboInfo.put("ubo_period_end", basisModel.getLarIdCardPeriodEnd().replace(".", "-"));
            }
            uboInfoList.add(uboInfo);
            subjectInfo.put("ubo_info_list", uboInfoList);
        }

        body.put("subject_info", subjectInfo);

        // 经营资料
        JSONObject 	businessInfo = new JSONObject();
        businessInfo.put("merchant_shortname", basisModel.getStoreModel().getName());
        businessInfo.put("service_phone", basisModel.getStoreModel().getTelephone());

        // 经营场景
        List<String> salesScenesType = new ArrayList();
        salesScenesType.add("SALES_SCENES_STORE");
        JSONObject salesInfo = new JSONObject();
        salesInfo.put("sales_scenes_type", salesScenesType);

        // 线下场所场景
        JSONObject bizStoreInfo = new JSONObject();
        bizStoreInfo.put("biz_store_name", basisModel.getStoreModel().getName());
        bizStoreInfo.put("biz_address_code", basisModel.getStoreModel().getStoreRegion().getAreaCode().toString());
        bizStoreInfo.put("biz_store_address", basisModel.getStoreModel().getStoreRegion().getAddress());
        List<String> storeEntrancePicList = new ArrayList<>();
        List<BsMerAttach> storeEntrancePic = getMerAttach(MerAttachType.type4,true);
        for (BsMerAttach attach : storeEntrancePic) {
            storeEntrancePicList.add(attach.getFileUrl());
        }
        bizStoreInfo.put("store_entrance_pic", storeEntrancePicList);

        List<String> indoorPicList = new ArrayList<>();
        List<BsMerAttach> indoorPic = getMerAttach(MerAttachType.type4,true);
        for (BsMerAttach attach : indoorPic) {
            indoorPicList.add(attach.getFileUrl());
        }
        bizStoreInfo.put("indoor_pic", indoorPicList);
        salesInfo.put("biz_store_info", bizStoreInfo);
        businessInfo.put("sales_info", salesInfo);
        body.put("business_info", businessInfo);

        // 结算规则
        JSONObject 	settlementInfo = new JSONObject();
        BsIndustry industry = industryService.getDetailById(basisModel.getMerIndustry().getChildId());
        if (industry == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的行业");
        }

        String settlementId = null;
        if (basisModel.getMerType().equals(MerTypeEnum.status1.getNumber())) {
            settlementId = industry.getWechatSelfEmployedCode();
        } else if (basisModel.getMerType().equals(MerTypeEnum.status2.getNumber())) {
            settlementId = industry.getWechatCompanyCode();
        }
        if (settlementId == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "行业选择不正确");
        }
        settlementInfo.put("settlement_id", settlementId);
        settlementInfo.put("qualification_type", industry.getWechatName());
        body.put("settlement_info", settlementInfo);

        // 结算银行账户
        JSONObject 	bankAccountInfo = new JSONObject();
        bankAccountInfo.put("bank_account_type", MerSettleType.getDataByNumber(basisModel.getMerSettleAcct().getSettleType()).getWxCode());
        if (basisModel.getMerSettleAcct().getSettleType().equals(MerSettleType.status1.getNumber())) {
            bankAccountInfo.put("account_name", HttpClientBuilder.rsaEncryptOAEP(basisModel.getMerName()));
        } else {
            bankAccountInfo.put("account_name",HttpClientBuilder.rsaEncryptOAEP(basisModel.getRegName()));
        }
        bankAccountInfo.put("account_bank", basisModel.getMerSettleAcct().getBankName());
        bankAccountInfo.put("bank_address_code", basisModel.getMerSettleAcct().getOpenningBankCityCode().toString());
        bankAccountInfo.put("account_number", HttpClientBuilder.rsaEncryptOAEP(basisModel.getMerSettleAcct().getBankCardNo()));
        body.put("bank_account_info", bankAccountInfo);


        // 补充材料
        JSONObject additionInfo = new JSONObject();
        List<String> additionPicsList = new ArrayList<>();
        List<BsMerAttach> merAdditionPicsList = getMerAttach(MerAttachType.type99, false);
        if (merAdditionPicsList != null) {
            for (BsMerAttach merAttach : merAdditionPicsList) {
                additionPicsList.add(merAttach.getFileUrl());
            }
            additionInfo.put("business_addition_pics", additionPicsList);
            body.put("addition_info", additionInfo);
        }

        HttpClientBuilder httpClientBuilder = new HttpClientBuilder();
        JSONObject applymentObject = JSONObject.parseObject(httpClientBuilder.applyment(body));
        if (StringUtils.isNotBlank(applymentObject.getString("code"))) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, applymentObject.getString("message"));
        }
        BsMerContractRecord merContractRecord = new BsMerContractRecord();
        merContractRecord.setMerId(merId);
        merContractRecord.setPlatformType(PlatformTypeEnum.type4.getNumber());
        merContractRecord.setOrderNo(body.getString("business_code"));
        merContractRecord.setContractId(applymentObject.getString("applyment_id"));
        merContractRecord.setCreateTime(new Date());
        merContractRecordService.insertRecord(merContractRecord);

    }

    /**
     * 商户进件
     * @param storeId
     */
    public void addStore(Long storeId) throws Exception {
        StoreModel storeDetail = storeService.getStoreDetail(storeId);
        if (storeDetail.getAloneSettle() == null || !storeDetail.getAloneSettle().equals(true)) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "门店无法提交进件");
        }

        // 查询商户附件列表
        storeAttachList = storeAttachService.getAttachList(storeId, null);

        JSONObject body = new JSONObject();
        body.put("business_code", ""+storeDetail.getStoreNo()+""+System.currentTimeMillis());

        // 超级管理员
        JSONObject contactInfo = new JSONObject();
        contactInfo.put("contact_type", "LEGAL");
        contactInfo.put("contact_name", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getDutyPeopleName()));
        contactInfo.put("contact_email", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getDutyPeopleEmail()));
        contactInfo.put("mobile_phone", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getDutyPeoplePhone()));
        body.put("contact_info", contactInfo);

        // 主体资料
        JSONObject 	subjectInfo = new JSONObject();
        subjectInfo.put("subject_type", MerTypeEnum.getDataByNumber(storeDetail.getStoreType()).getWxCode());

        // 营业执照
        JSONObject businessLicenseInfo = new JSONObject();
        businessLicenseInfo.put("license_copy", getStoreAttach(StoreAttachType.type1).get(0).getFileUrl());
        businessLicenseInfo.put("license_number", storeDetail.getBlisNo());
        businessLicenseInfo.put("merchant_name", storeDetail.getBlisName());
        businessLicenseInfo.put("legal_person", storeDetail.getLarName());
        businessLicenseInfo.put("license_address", storeDetail.getBlisRegAddress());
        businessLicenseInfo.put("period_begin", storeDetail.getBlisPeriodStart().replace(".", "-"));
        if (storeDetail.getBlisPeriodType().equals(2)) {
            businessLicenseInfo.put("period_end", "长期");
        } else {
            businessLicenseInfo.put("period_end", storeDetail.getBlisPeriodEnd().replace(".", "-"));
        }
        JSONArray uboInfoList = new JSONArray();
        JSONObject uboInfo = new JSONObject();
        uboInfo.put("ubo_id_doc_type", "IDENTIFICATION_TYPE_IDCARD");
        uboInfo.put("ubo_id_doc_copy", getStoreAttach(StoreAttachType.type2).get(0).getFileUrl());
        uboInfo.put("ubo_id_doc_copy_back", getStoreAttach(StoreAttachType.type3).get(0).getFileUrl());
        uboInfo.put("ubo_id_doc_name", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getLarName()));
        uboInfo.put("ubo_id_doc_number", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getLarIdCard()));
        uboInfo.put("ubo_id_doc_address", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getLarIdCardAddress()));
        uboInfo.put("ubo_period_begin", storeDetail.getLarIdCardPeriodStart().replace(".", "-"));
        if (storeDetail.getLarIdCardPeriodType().equals(2)) {
            uboInfo.put("ubo_period_end", "长期");
        } else {
            uboInfo.put("ubo_period_end", storeDetail.getLarIdCardPeriodEnd().replace(".", "-"));
        }
        uboInfoList.add(uboInfo);

        businessLicenseInfo.put("ubo_info_list", uboInfoList);
        subjectInfo.put("business_license_info", businessLicenseInfo);

        // 经营者/法人身份证件
        JSONObject identityInfo = new JSONObject();
        identityInfo.put("id_holder_type", "LEGAL");
        identityInfo.put("id_doc_type", "IDENTIFICATION_TYPE_IDCARD");
        identityInfo.put("owner", true);

        // 当证件持有人类型为经营者/法人且证件类型为“身份证”时填写。
        JSONObject idCardInfo = new JSONObject();
        idCardInfo.put("id_card_copy", getStoreAttach(StoreAttachType.type2).get(0).getFileUrl());
        idCardInfo.put("id_card_national", getStoreAttach(StoreAttachType.type3).get(0).getFileUrl());
        idCardInfo.put("id_card_name", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getLarName()));
        idCardInfo.put("id_card_number", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getLarIdCard()));
        idCardInfo.put("id_card_address", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getLarIdCardAddress()));
        idCardInfo.put("card_period_begin", storeDetail.getLarIdCardPeriodStart().replace(".", "-"));
        if (storeDetail.getLarIdCardPeriodType().equals(2)) {
            idCardInfo.put("card_period_end", "长期");
        } else {
            idCardInfo.put("card_period_end", storeDetail.getLarIdCardPeriodEnd().replace(".", "-"));
        }
        identityInfo.put("id_card_info", idCardInfo);
        subjectInfo.put("identity_info", identityInfo);

        body.put("subject_info", subjectInfo);

        // 经营资料
        JSONObject 	businessInfo = new JSONObject();
        businessInfo.put("merchant_shortname", storeDetail.getName());
        businessInfo.put("service_phone", storeDetail.getTelephone());

        // 经营场景
        List<String> salesScenesType = new ArrayList();
        salesScenesType.add("SALES_SCENES_STORE");
        JSONObject salesInfo = new JSONObject();
        salesInfo.put("sales_scenes_type", salesScenesType);

        // 线下场所场景
        JSONObject bizStoreInfo = new JSONObject();
        bizStoreInfo.put("biz_store_name", storeDetail.getName());
        bizStoreInfo.put("biz_address_code", storeDetail.getStoreRegion().getAreaCode().toString());
        bizStoreInfo.put("biz_store_address", storeDetail.getStoreRegion().getAddress());
        List<String> storeEntrancePicList = new ArrayList<>();
        List<BsStoreAttach> storeEntrancePic = getStoreAttach(StoreAttachType.type4);
        for (BsStoreAttach attach : storeEntrancePic) {
            storeEntrancePicList.add(attach.getFileUrl());
        }
        bizStoreInfo.put("store_entrance_pic", storeEntrancePicList);

        List<String> indoorPicList = new ArrayList<>();
        List<BsStoreAttach> indoorPic = getStoreAttach(StoreAttachType.type4);
        for (BsStoreAttach attach : indoorPic) {
            indoorPicList.add(attach.getFileUrl());
        }
        bizStoreInfo.put("indoor_pic", indoorPicList);
        salesInfo.put("biz_store_info", bizStoreInfo);
        businessInfo.put("sales_info", salesInfo);
        body.put("business_info", businessInfo);

        // 结算规则
        JSONObject 	settlementInfo = new JSONObject();
        settlementInfo.put("settlement_id", storeDetail.getStoreType().equals(MerTypeEnum.status1.getNumber())?"719":"716");
        settlementInfo.put("qualification_type", storeDetail.getStoreIndustry().getParentName());
        body.put("settlement_info", settlementInfo);

        // 结算银行账户
        JSONObject 	bankAccountInfo = new JSONObject();
        bankAccountInfo.put("bank_account_type", MerSettleType.getDataByNumber(storeDetail.getStoreSettleAcct().getSettleType()).getWxCode());
        if (storeDetail.getStoreSettleAcct().getSettleType().equals(MerSettleType.status1.getNumber())) {
            bankAccountInfo.put("account_name", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getName()));
        } else {
            bankAccountInfo.put("account_name",HttpClientBuilder.rsaEncryptOAEP(storeDetail.getDutyPeopleName()));
        }
        bankAccountInfo.put("account_bank", storeDetail.getStoreSettleAcct().getBankName());
        bankAccountInfo.put("bank_address_code", "110000");
        bankAccountInfo.put("account_number", HttpClientBuilder.rsaEncryptOAEP(storeDetail.getStoreSettleAcct().getBankCardNo()));
        body.put("bank_account_info", bankAccountInfo);

        HttpClientBuilder httpClientBuilder = new HttpClientBuilder();
        JSONObject applymentObject = JSONObject.parseObject(httpClientBuilder.applyment(body));
        if (StringUtils.isNotBlank(applymentObject.getString("code"))) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, applymentObject.getString("message"));
        }
        BsStoreContractRecord merContractRecord = new BsStoreContractRecord();
        merContractRecord.setStoreId(storeId);
        merContractRecord.setPlatformType(PlatformTypeEnum.type4.getNumber());
        merContractRecord.setOrderNo(body.getString("business_code"));
        merContractRecord.setContractId(applymentObject.getString("applyment_id"));
        merContractRecord.setCreateTime(new Date());
        storeContractRecordService.editContractRecord(merContractRecord);
    }

    /**
     * 查询进件状态
     * @param applymentId
     * @return
     */
    public JSONObject getApplyment(String applymentId) throws IOException {
        HttpClientBuilder httpClient = new HttpClientBuilder();
        return JSONObject.parseObject(httpClient.getApplyment(applymentId));
    }

    /**
     * 获取商户附件
     * @param attachType
     * @param check 检查是否上传，true：抛出异常 false: 不检查
     * @return
     */
    private List<BsMerAttach> getMerAttach(MerAttachType attachType, Boolean check) {
        if (merAttachList == null || merAttachList.size() == 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未上传相关图片");
        }
        List<BsMerAttach> collect = merAttachList.stream()
                .filter(o -> o.getType().equals(attachType.getNumber()))
                .collect(Collectors.toList());
        if (check == true && collect.size() == 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未上传" + attachType.getName() + "图片");
        }
        return collect;
    }

    /**
     * 获取门店附件
     * @param attachType
     * @return
     */
    private List<BsStoreAttach> getStoreAttach(StoreAttachType attachType) {
        if (storeAttachList == null || storeAttachList.size() == 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未上传相关图片");
        }
        List<BsStoreAttach> collect = storeAttachList.stream()
                .filter(o -> o.getType().equals(attachType.getNumber()))
                .collect(Collectors.toList());
        if (collect.size() == 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未上传" + attachType.getName() + "图片");
        }
        return collect;
    }
}
