package com.yunzhi.marketing.eContract.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fadada.sdk.client.FddClientBase;
import com.fadada.sdk.client.authForfadada.FindCertInfo;
import com.fadada.sdk.client.request.ExtsignReq;
import com.fadada.sdk.util.http.HttpsUtil;
import com.yunzhi.marketing.base.ResponseBean;
import com.yunzhi.marketing.bo.request.ContractRecordRequestBO;
import com.yunzhi.marketing.common.MD5Utils;
import com.yunzhi.marketing.common.StringUtils;
import com.yunzhi.marketing.config.FadadaProperties;
import com.yunzhi.marketing.eContract.entity.TaContract;
import com.yunzhi.marketing.eContract.entity.TaContractBusiness;
import com.yunzhi.marketing.eContract.entity.TaContractUser;
import com.yunzhi.marketing.eContract.mapper.TaContractMapper;
import com.yunzhi.marketing.eContract.mapper.TaContractUserMapper;
import com.yunzhi.marketing.eContract.service.ITaContractService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunzhi.marketing.entity.TaMiniapp;
import com.yunzhi.marketing.entity.TaPerson;
import com.yunzhi.marketing.entity.TaRaiseRecord;
import com.yunzhi.marketing.mapper.TaMiniappMapper;
import com.yunzhi.marketing.mapper.TaOrgMapper;
import com.yunzhi.marketing.mapper.TaRaiseRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * <p>
 * 合同列表  服务实现类
 * </p>
 *
 * @author fxf
 * @since 2020-03-26
 */
@Service
@Slf4j
public class TaContractServiceImpl extends ServiceImpl<TaContractMapper, TaContract> implements ITaContractService {

    @Autowired
    private FadadaProperties fadadaProperties;

    @Autowired
    private TaContractMapper taContractMapper;

    @Autowired
    private TaRaiseRecordMapper taRaiseRecordMapper;

    @Autowired
    private TaOrgMapper taOrgMapper;

    @Autowired
    private TaContractUserMapper taContractUserMapper;

    @Autowired
    private TaMiniappMapper taMiniappMapper;


    @Override
    public ResponseBean listContractForAdmin(Integer pageNum, Integer pageSize, String contractName, Boolean archives, String signatoryName, Integer signatoryStatus, String customerName, Integer customerStatus, LocalDate archivesStartDate, LocalDate archivesEndDate, Integer orgId) {

        ResponseBean responseBean = new ResponseBean();
        IPage<TaContract> pg = new Page<>(pageNum, pageSize);
        pg = taContractMapper.listContractForAdmin(pg, contractName, archives, signatoryName, signatoryStatus, customerName, customerStatus, archivesStartDate, archivesEndDate, orgId);
        responseBean.addSuccess(pg);
        return responseBean;
    }

    @Override
    public ResponseBean listContractForChannel(ContractRecordRequestBO requestBO) {
        log.info("TaContractServiceImpl.listContractForChannel 接收参数:{}", JSONObject.toJSONString(requestBO));

        ResponseBean responseBean = new ResponseBean();

        IPage<TaContract> pg = new Page<>(requestBO.getPageNum(), requestBO.getPageSize());
        pg = taContractMapper.listContractForChannel(pg, requestBO);
        responseBean.addSuccess(pg);
        return responseBean;
    }

    /**
     * 企业自动签署合同
     *
     * @param taRaiseRecord
     * @param person
     * @return
     */
    @Override
    @Transactional
    public TaContract autoContract(TaRaiseRecord taRaiseRecord, TaPerson person) throws Exception {
        taRaiseRecord = taRaiseRecordMapper.selectById(taRaiseRecord.getRaiseRecordId());



        //根据raiseId获取合同的所有参数
        TaContractBusiness taContractBusiness = taContractMapper.selectContractInfoByRaiseId(taRaiseRecord.getRaiseId());
        if (null == taContractBusiness){
            throw new Exception("无合同模板，请和置业顾问联系");
        }

        //检查是否签署过本合同
        QueryWrapper<TaContract> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("building_id",taRaiseRecord.getBuildingId());
        queryWrapper.eq("org_id",taRaiseRecord.getOrgId());
        queryWrapper.eq("target_type","raise");
        queryWrapper.eq("target_id",Integer.valueOf(taRaiseRecord.getRaiseId()));
        queryWrapper.eq("invoice_target_type","raise_record");
        queryWrapper.eq("invoice_target_id",taRaiseRecord.getRaiseRecordId());
        queryWrapper.eq("company_id",taContractBusiness.getCompanyId());
        queryWrapper.eq("person_id",person.getPersonId());
        TaContract oldContract = taContractMapper.selectOne(queryWrapper);
        if (null != oldContract){
            oldContract.setContractDownloadUrl(getFddServerHost(person.getMiniappId(),oldContract.getContractDownloadUrl()));
            oldContract.setContractViewUrl(getFddServerHost(person.getMiniappId(),oldContract.getContractViewUrl()));
            return oldContract;
        }

        //先入合同表
        TaContract taContract = new TaContract();
        taContract.setBuildingId(taRaiseRecord.getBuildingId());
        taContract.setOrgId(taRaiseRecord.getOrgId());
        taContract.setOrgName(taOrgMapper.selectById(taRaiseRecord.getOrgId()).getName());
        taContract.setTargetType("raise");
        taContract.setTargetId(Integer.valueOf(taRaiseRecord.getRaiseId()));
        taContract.setInvoiceTargetType("raise_record");
        taContract.setInvoiceTargetId(taRaiseRecord.getRaiseRecordId());
        taContract.setCompanyId(taContractBusiness.getCompanyId());
        taContract.setCreateDate(LocalDateTime.now());
        taContract.setStatus(0);
        taContract.setPersonId(person.getPersonId());
        taContractMapper.insert(taContract);

        //上传合同
        FddClientBase base = new FddClientBase(fadadaProperties.getAppId(),fadadaProperties.getAppSecret(),fadadaProperties.getVersion(),fadadaProperties.getServeHost());
        String result = base.invokeUploadDocs(taContract.getContractId().toString(), taContractBusiness.getContractTemplateName(), null, taContractBusiness.getContractTemplateAddress(), ".pdf");
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (!jsonObject.getString("code").equals("1000")){
            taContractMapper.deleteById(taContract.getContractId());
            throw new Exception(jsonObject.getString("msg"));
        }

        //自动签署合同
        String timeStamp = HttpsUtil.getTimeStamp();
        String transaction_id = "TRAN_" + timeStamp;
        ExtsignReq req = new ExtsignReq();
        req.setCustomer_id(taContractBusiness.getFadadaCode());
        req.setTransaction_id(transaction_id);
        req.setContract_id(taContract.getContractId().toString());
        req.setClient_role("1");
        req.setSign_keyword(taContractBusiness.getSignatoryKeywords());
        req.setKeyword_strategy(taContractBusiness.getSignatoryStrategy());
        req.setDoc_title(taContractBusiness.getContractTemplateName());
        String autoSignResult = base.invokeExtSignAuto(req,taContractBusiness.getSignatureId());
        JSONObject autoSignResultJson = JSONObject.parseObject(autoSignResult);
        if (!autoSignResultJson.getString("code").equals("1000")){
            throw new Exception(jsonObject.getString("msg"));
        }

        //反更新合同地址
        taContract.setContractDownloadUrl(getFddServerHost(person.getMiniappId(),autoSignResultJson.getString("download_url")));
        taContract.setContractViewUrl(getFddServerHost(person.getMiniappId(),autoSignResultJson.getString("viewpdf_url")));
        taContract.setContractName(taContractBusiness.getContractTemplateName());
        //合同详情
        taContract.setCompanyName(taContractBusiness.getCompanyName());
        taContract.setSignatoryName(taContractBusiness.getCompanyName());
        taContract.setSignatoryTime(LocalDateTime.now());
        taContract.setArchives(false);
        taContractMapper.updateById(taContract);
        return taContract;
    }

    /**
     * 替换法大大服务器地址
     * @return
     */
    private String getFddDownServerHost(String miniappId,String subUrl) {
        if (StringUtils.isEmpty(subUrl)){
            return 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.getFddDownloadHost()) ? subUrl : taMiniapp.getFddDownloadHost() + subUrl.substring(threeIndex);
        return newUrl;
    }

    /**
     * 手动签署合同
     *
     * @param taContract
     * @param person
     * @return
     */
    @Override
    public String manualContract(TaContract taContract, TaPerson person) throws Exception {
        //获取客户信息
        QueryWrapper<TaContractUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mini_openid", MD5Utils.md5(person.getMiniOpenid()));
        TaContractUser taContractUser = taContractUserMapper.selectOne(queryWrapper);

        if (taContract.getStatus() == 1){
            throw new Exception("已经成功签署，无需再次签署");
        }
        //根据raiseId获取合同的所有参数
        TaContractBusiness taContractBusiness = taContractMapper.selectContractInfoByRaiseId(taContract.getTargetId().toString());
        if (null == taContractBusiness){
            throw new Exception("无合同模板，请和置业顾问联系");
        }

        //手动签署合同
        String timeStamp = HttpsUtil.getTimeStamp();
        String transaction_id = "TRAN_" + timeStamp;

        FddClientBase base = new FddClientBase(fadadaProperties.getAppId(),fadadaProperties.getAppSecret(),fadadaProperties.getVersion(),fadadaProperties.getServeHost());
        ExtsignReq req = new ExtsignReq();
        req.setCustomer_id(taContractUser.getFadadaCode());
        req.setTransaction_id(transaction_id);
        req.setContract_id(taContract.getContractId().toString());
        req.setSign_keyword(taContractBusiness.getCustomerKeywords());
        req.setKeyword_strategy(taContractBusiness.getCustomerStrategy());

        req.setDoc_title(taContractBusiness.getContractTemplateName());
        String redirectUrl = URLEncoder.encode(URLEncoder.encode(
                "/onlineSelling/pages/raiseMoney/signResult?id=" + taContract.getInvoiceTargetId(), "utf-8"), "utf-8");
        String return_url=  fadadaProperties.getRedirectUrl() + "?appid=123&redirect="+ redirectUrl;
        req.setReturn_url(URLEncoder.encode(return_url, "utf-8"));
        req.setNotify_url(fadadaProperties.getSignNotify());
        String signUrl = base.invokeExtSignDIY(req,"1","0");

        //更新乙方数据
        //获取个人信息
        log.info("个人正在从法大大获取最新数据，企业编号是 {}", taContractUser.getFadadaCode());
        FindCertInfo personCertInfo = new FindCertInfo(fadadaProperties.getAppId(),fadadaProperties.getAppSecret(),fadadaProperties.getVersion(),fadadaProperties.getServeHost());
        String verified_serialno = taContractUser.getCertifiedSerialNumber();
        String result = personCertInfo.invokeFindPersonCert(verified_serialno,
                "1");
        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 personJson = dataJson.getJSONObject("person");
            if (null != personJson){
                taContract.setCustomerName(personJson.getString("personName"));
                taContract.setCustomerTel(personJson.getString("mobile"));
                taContract.setCustomerIdcard(personJson.getString("idCard"));
            }
        }

        taContractMapper.updateById(taContract);
        String manualUrl = getFddServerHost(person.getMiniappId(), signUrl);
        return manualUrl;
    }


    /**
     * 替换法大大服务器地址
     * @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;
    }

    /**
     * 检查签署合同状态
     *
     * @param taRaiseRecord
     * @param person
     * @return
     */
    @Override
    public TaContract checkContract(TaRaiseRecord taRaiseRecord, TaPerson person) throws Exception {
        taRaiseRecord = taRaiseRecordMapper.selectById(taRaiseRecord.getRaiseRecordId());

        //根据raiseId获取合同的所有参数
        TaContractBusiness taContractBusiness = taContractMapper.selectContractInfoByRaiseId(taRaiseRecord.getRaiseId());
        if (null == taContractBusiness){
            throw new Exception("无合同模板，请和置业顾问联系");
        }

        //检查是否签署过本合同
        QueryWrapper<TaContract> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("building_id",taRaiseRecord.getBuildingId());
        queryWrapper.eq("org_id",taRaiseRecord.getOrgId());
        queryWrapper.eq("target_type","raise");
        queryWrapper.eq("target_id",Integer.valueOf(taRaiseRecord.getRaiseId()));
        queryWrapper.eq("invoice_target_type","raise_record");
        queryWrapper.eq("invoice_target_id",taRaiseRecord.getRaiseRecordId());
        queryWrapper.eq("company_id",taContractBusiness.getCompanyId());
        queryWrapper.eq("person_id",person.getPersonId());
        TaContract oldContract = taContractMapper.selectOne(queryWrapper);
        oldContract.setContractDownloadUrl(getFddServerHost(person.getMiniappId(),oldContract.getContractDownloadUrl()));
        oldContract.setContractViewUrl(getFddServerHost(person.getMiniappId(),oldContract.getContractViewUrl()));
        return oldContract;
    }
}
