package com.huiju.estateagents.eContract.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fadada.sdk.client.FddClientBase;
import com.fadada.sdk.client.authForfadada.FindCertInfo;
import com.fadada.sdk.client.authForfadada.GetCompanyVerifyUrl;
import com.fadada.sdk.client.authForfadada.model.AgentInfoINO;
import com.fadada.sdk.client.authForfadada.model.BankInfoINO;
import com.fadada.sdk.client.authForfadada.model.CompanyInfoINO;
import com.fadada.sdk.client.authForfadada.model.LegalInfoINO;
import com.fadada.sdk.util.http.HttpsUtil;
import com.huiju.estateagents.common.CommConstant;
import com.huiju.estateagents.common.StringUtils;
import com.huiju.estateagents.config.FadadaProperties;
import com.huiju.estateagents.controller.CommonController;
import com.huiju.estateagents.eContract.entity.TaCompany;
import com.huiju.estateagents.eContract.entity.TaContract;
import com.huiju.estateagents.eContract.mapper.TaCompanyMapper;
import com.huiju.estateagents.eContract.mapper.TaContractMapper;
import com.huiju.estateagents.eContract.service.ITaCompanyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huiju.estateagents.entity.TaMiniapp;
import com.huiju.estateagents.mapper.TaMiniappMapper;
import com.huiju.estateagents.sample.entity.TaContact;
import com.huiju.estateagents.sample.mapper.TaContactMapper;
import jodd.util.URLDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * <p>
 * 企业认证表  服务实现类
 * </p>
 *
 * @author fxf
 * @since 2020-03-26
 */
@Slf4j
@Service
public class TaCompanyServiceImpl extends ServiceImpl<TaCompanyMapper, TaCompany> implements ITaCompanyService {

    @Autowired
    private FadadaProperties fadadaProperties;

    @Autowired
    private TaCompanyMapper taCompanyMapper;

    @Autowired
    private TaContractMapper taContractMapper;

    @Autowired
    private TaCompanySealUtil taCompanySealUtil;

    @Autowired
    private TaMiniappMapper taMiniappMapper;

    /**
     * 在法大大创建一个新的企业信息
     *
     * @return
     */
    @Override
    public TaCompany newFirstCompanyInfo() throws Exception {
        log.info("========法大大企业注册=======");
        //在法大大注册企业用户
        FddClientBase base = new FddClientBase(fadadaProperties.getAppId(),fadadaProperties.getAppSecret(),fadadaProperties.getVersion(),fadadaProperties.getServeHost());
        String open_id = "CJ_" + HttpsUtil.getTimeStamp();
        String account_type = CommConstant.ACCOUNT_TYPE_COMPANY;
        String result =base.invokeregisterAccount(open_id,account_type);
        log.info("法大大注册信息{}", result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getInteger("code") != 1){
            throw new Exception(jsonObject.getString("msg"));
        }

        //插入企业数据表
        TaCompany taCompany = new TaCompany();
        taCompany.setCompanyCode(open_id);
        taCompany.setFadadaCode(jsonObject.getString("data"));
        taCompany.setCertifiedStatus(CommConstant.CERTIFIED_STATUS_REGISTERED);
        taCompany.setCreateDate(LocalDateTime.now());
        taCompany.setStatus(CommConstant.STATUS_UNACCALIMED);
        taCompanyMapper.insert(taCompany);
        return taCompany;
    }

    /**
     * 向法大大申请企业认证
     *
     * @param taCompany
     * @return
     */
    @Override
    public TaCompany updateCompanyInfo(TaCompany taCompany) throws Exception {
        String companyPrincipalType = "1";
        //法人
        if (taCompany.getCompanyManagerType().equals(CommConstant.COMPANY_MANAGER_TYPE_LEGAL)){
            companyPrincipalType = CommConstant.COMPANY_PRINCIPAL_TYPE_LEGAL;
        }else if (taCompany.getCompanyManagerType().equals(CommConstant.COMPANY_MANAGER_TYPE_AGENT)){
            companyPrincipalType = CommConstant.COMPANY_PRINCIPAL_TYPE_AGENT;
        }
        log.info("正在申请企业认证,客户编码是{}",taCompany.getFadadaCode());
        //和法大大申请认证页面
        GetCompanyVerifyUrl comverify = new GetCompanyVerifyUrl(fadadaProperties.getAppId(),fadadaProperties.getAppSecret(),fadadaProperties.getVersion(),fadadaProperties.getServeHost());
        //客户编号必填
        String customer_id = taCompany.getFadadaCode();
        /**
         * 实名认证套餐类型
         * 0：标准方案（对公打款+纸质审核）默认0；
         * 1：对公打款；
         * 2：纸质审核',
         */
        String verifyed_way = "0";
        //是否允许客户页面修改1允许
        String page_modify = "1";
        String m_verified_way = "1";
        //跳转指定页面
        String resultType = "1";
        //自动申请证书
        String certFlag = "1";

        String notify_url = fadadaProperties.getCompanyNotify();
        String result = comverify.invokeCompanyVerifyUrl(new CompanyInfoINO(), new BankInfoINO(),new LegalInfoINO()
                ,new AgentInfoINO(), customer_id,verifyed_way,m_verified_way,page_modify,
                companyPrincipalType,null,notify_url,resultType,certFlag);
        log.info("企业认证结果通知{}",result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getInteger("code") != 1){
            throw new Exception(jsonObject.getString("msg"));
        }
        String data = jsonObject.getString("data");
        if (null !=data){
            String url = JSON.parseObject(data).getString("url");
            url = decode(url);
            taCompany.setCertifiedAddress(url);
            taCompany.setCertifiedSerialNumber(JSON.parseObject(data).getString("transactionNo"));
        }
        taCompany.setCertifiedStatus(CommConstant.CERTIFIED_STATUS_CERTIFICATION);
        taCompanyMapper.updateById(taCompany);
        return taCompany;
    }

    /**
     * 向法大大获取最新的企业认证数据
     *
     * @param id
     * @return
     */
    @Override
    public TaCompany updateCompanyInfoByFdd(Integer id) throws Exception {
        TaCompany taCompany = taCompanyMapper.selectById(id);
        log.info("企业正在从法大大获取最新数据，企业编号是 {}", taCompany.getFadadaCode());
        FindCertInfo personCertInfo = new FindCertInfo(fadadaProperties.getAppId(),fadadaProperties.getAppSecret(),fadadaProperties.getVersion(),fadadaProperties.getServeHost());
        String verified_serialno = taCompany.getCertifiedSerialNumber();
        String result = personCertInfo.invokeFindPersonCert(verified_serialno, CommConstant.ACCOUNT_TYPE_COMPANY);
        log.info("企业最新数据结果 {}",result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getInteger("code") != 1){
            throw new Exception(jsonObject.getString("msg"));
        }
        //更新数据
        String data = jsonObject.getString("data");
        if (null !=data){
            JSONObject dataJson = JSONObject.parseObject(data);
            //账户信息
            JSONObject companyJson = dataJson.getJSONObject("company");
            if (null != companyJson){
                taCompany.setCompanyName(companyJson.getString("companyName"));
                taCompany.setCertifiedType(companyJson.getInteger("verifyType"));
                taCompany.setCreditCode(companyJson.getString("organization"));
                taCompany.setStatus(companyJson.getInteger("status"));
                taCompany.setReason(companyJson.getString("auditFailReason"));
                taCompany.setVerifyTime(null);
                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                String auditorTime = companyJson.getString("auditorTime");
                if (!StringUtils.isEmpty(auditorTime)){
                    int index = auditorTime.lastIndexOf(".");
                    String substringTime = auditorTime.substring(0, index);
                    taCompany.setVerifyTime(LocalDateTime.parse(substringTime,df));
                }

            }

            //银行卡信息
            JSONObject bankJson = dataJson.getJSONObject("bankCard");
            if (null != bankJson){
                taCompany.setBankName(bankJson.getString("bankName"));
                taCompany.setSubbranchName(bankJson.getString("bankDetailName"));
                taCompany.setBankAccount(bankJson.getString("bankCardNo"));
            }

            //企业法人、代理人信息
            JSONObject managerJson = dataJson.getJSONObject("manager");
            if (null != managerJson){
                //0：个人； 1：法人； 2：代理人,
                if (managerJson.getString("type").equals("1")){
                    taCompany.setCompanyManagerType("legal");
                }else if (managerJson.getString("type").equals("2")){
                    taCompany.setCompanyManagerType("agent");
                }
                taCompany.setUserName(managerJson.getString("personName"));
                taCompany.setTel(managerJson.getString("mobile"));
                taCompany.setIdCard(managerJson.getString("idCard"));
            }
        }
        taCompanyMapper.updateById(taCompany);
        return taCompany;
    }

    @Override
    public String autoAuthCompanySeal(Integer companyId, Integer orgId) throws Exception {
        QueryWrapper<TaContract> taContractQueryWrapper = new QueryWrapper<>();
        taContractQueryWrapper.eq("target_type", CommConstant.AUTH);
        taContractQueryWrapper.eq("company_id", companyId);
        taContractQueryWrapper.eq("status", CommConstant.STATUS_NORMAL);
        TaContract taContract = taContractMapper.selectOne(taContractQueryWrapper);

        TaCompany taCompany = taCompanyMapper.selectById(companyId);
        String timeStamp = HttpsUtil.getTimeStamp();
        String transactionId = "TRAN" + timeStamp;
        if (taContract == null){
            taContract = new TaContract();
            taContract.setCompanyId(companyId);
            taContract.setOrgId(orgId);
            taContract.setCreateDate(LocalDateTime.now());
            taContract.setTargetType(CommConstant.AUTH);
            taContract.setSignatoryName(taCompany.getCompanyName());
            taContract.setCustomerName("法大大公司平台");
            taContract.setSignatoryTime(LocalDateTime.now());
            taContract.setCustomerTime(LocalDateTime.now());
            taContract.setStatus(CommConstant.STATUS_UNACCALIMED);
            taContract.setOrgId(orgId);
            taContractMapper.insert(taContract);
        }else{
            taContract.setSignatoryTime(LocalDateTime.now());
            taContract.setCustomerTime(LocalDateTime.now());
            taContractMapper.updateById(taContract);
        }

        Integer contractId = taContract.getContractId();
        String customerId = taCompany.getFadadaCode();
        String res = taCompanySealUtil.autoAuthCompanySeal(transactionId, CommConstant.AUTH_TYPE, String.valueOf(contractId), customerId, String.valueOf(companyId));
        return res;
    }

    @Override
    public TaCompany getCompanyAndContractInfo(Integer companyId) {
        return taCompanyMapper.getCompanyAndContractInfo(companyId);
    }

    @Override
    public String getAuthStatus(Integer companyId) {
        TaCompany taCompany = taCompanyMapper.selectById(companyId);
        return taCompanySealUtil.getAuthStatus(taCompany.getFadadaCode());
    }

    @Override
    public IPage<TaCompany> selectListByOrgId(IPage<TaCompany> iPage, String companyName, String companyCode, Integer orgId) {
        return taCompanyMapper.selectListByOrgId(iPage, companyName, companyCode, orgId);
    }

    /**
     * url解码
     * @param bizContent
     * @return
     */
    private String decode(String bizContent) {
        bizContent = URLDecoder.decode(bizContent, "utf-8");
        bizContent = new String(Base64.decodeBase64(bizContent.getBytes()));
        return bizContent;
    }

    /**
     * 替换法大大服务器地址
     * @return
     */
    private String getFddServerHost(String miniappId,String subUrl) {
        TaMiniapp taMiniapp = taMiniappMapper.selectById(miniappId);
        int index = subUrl.indexOf("/");
        int twoIndex = subUrl.indexOf("/",index+1);
        int threeIndex = subUrl.indexOf("/",twoIndex+1);
        String newUrl = StringUtils.isEmpty(taMiniapp.getFddServerHost()) ? subUrl : taMiniapp.getFddServerHost() + subUrl.substring(threeIndex);
        return newUrl;
    }
}
