package com.seeyon.apps.esign.service;

import com.seeyon.apps.esign.config.EsignConfigProvider;
import com.seeyon.apps.esign.constants.EsignConfigConstants;
import com.seeyon.apps.esign.po.param.FlowParamSource;
import com.seeyon.apps.esign.po.signer.DefaultSignerBuilder;
import com.seeyon.apps.esign.po.signer.SignParty;
import com.seeyon.apps.esign.po.signer.Signer;
import com.seeyon.apps.ext.workflow.vo.FieldDataVo;
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
import com.seeyon.ctp.common.AppContext;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FlowFormSignParamBuildFactory implements SignParamBuildFactory {
    private EsignConfigProvider configProvider = EsignConfigProvider.getInstance();
    private EsignUploadFileService uploadFileService = (EsignUploadFileService) AppContext.getBean("esignUploadFileService");

    @Override
    public Map<String, Object> buildParam(SignParamSource source) throws Exception {
        Map<String, Object> signParams = new HashMap<>();
        List<String> fileIds = null;
        if (source.isByFile()) {
            String attachmentId = source.getSignFileRefId();
            if (attachmentId == null) throw new RuntimeException("合同文件不能为空");
            List<Map<String, Object>> docs = buildDocs(source.getAppId(),attachmentId);
            fileIds = new ArrayList<>();
            for (Map<String, Object> doc : docs) {
                fileIds.add((String) doc.get("fileId"));
            }
            signParams.put("docs", docs);
        }
        Map<String, Object> signFlowConfig = buildSignFlowConfig(source.getContractTitle(),source.getCallbackUrl());
        DefaultSignerBuilder signerBuilder = new DefaultSignerBuilder();
        List<SignParty> signerParties = source.getSignerParties();
        List<Object> keywordPos = new ArrayList<>();
        if (source.useKeyWordPositioning()) {
            String aSignPosKeyword = configProvider.getBizConfigByKey(EsignConfigConstants.aSignPositionKeyword);
            String bSignPosKeyword = configProvider.getBizConfigByKey(EsignConfigConstants.bSignPositionKeyword);
            String lpSignPosKeyword = configProvider.getBizConfigByKey(EsignConfigConstants.lpSignPositionKeyword);
            List<String> keywords = new ArrayList<>();
            for (SignParty party : signerParties) {
                if ("防伪章签署方".equals(party.getPartyId())) {
                    continue;
                }
                String keyword = getKeywordByPartyId(party.getPartyId(), aSignPosKeyword, bSignPosKeyword, lpSignPosKeyword);
                if (StringUtils.isNotBlank(keyword)) {
                    party.setSignKeyword(keyword);
                    keywords.add(keyword);
                }
            }
            keywordPos = getKeywordPos(source.getAppId(), fileIds, keywords);
        }
        List<Signer> signers = signerBuilder.buildAll(fileIds,keywordPos,signerParties,source.getAppId());
        signParams.put("signFlowConfig", signFlowConfig);
        signParams.put("signers", signers);
        return signParams;
    }

    @Override
    public boolean support(SignParamSource source) {
        return source instanceof FlowParamSource;
    }

    private List<Object> getKeywordPos(String appId,List<String> fileIds,List<String> keywords){
        List<Object> pos = new ArrayList<>();
        if(keywords.isEmpty()) {
            return pos;
        }
        for (String fileId : fileIds){
            List<Object> signPosition = uploadFileService.getSignPosition(appId,fileId, keywords);
            pos.addAll(signPosition);
        }
        return pos;
    }

    /**
     * 构建文档列表
     * @param attachmentId 如果 byFile=true，则上传并返回 fileId
     */
    public List<Map<String, Object>> buildDocs(String appId,String attachmentId) throws Exception {
        List<String> fileIds = uploadFileService.uploadFileToEsign(appId,attachmentId);
        List<Map<String, Object>> docs = new ArrayList<>();
        for (String fileId : fileIds) {
            Map<String, Object> docMap = new HashMap<>();
            docMap.put("fileId", fileId);
            docs.add(docMap);
        }
        Thread.sleep(1000); // e签宝要求，可考虑异步
        return docs;
    }

    public Map<String, Object> buildSignFlowConfig(String contractName,String callbackUrl) throws Exception {
        if (contractName == null) throw new RuntimeException("合同名称不能为空");
        String signCallBackUrl = configProvider.getBizConfigByKey(EsignConfigConstants.OA_HOST) + callbackUrl;
        Map<String, Object> config = new HashMap<>();
        config.put("signFlowTitle", contractName);
        config.put("autoFinish", true);
        config.put("notifyUrl", signCallBackUrl);
        Map<String, Object> noticeConfig = new HashMap<>();
        noticeConfig.put("noticeTypes", "1");
        config.put("noticeConfig", noticeConfig);
        Map<String, Object> signConfig = new HashMap<>();
        signConfig.put("showBatchDropSealButton", false);
        config.put("signConfig", signConfig);
        return config;
    }

    private String getKeywordByPartyId(String partyId, String aKeyword, String bKeyword, String lpKeyword) {
        if ("甲方".equals(partyId)) {
            return aKeyword;
        } else if ("乙方".equals(partyId)) {
            return bKeyword;
        } else if ("法定代表人".equals(partyId)) {
            return lpKeyword;
        }
        return null;
    }

    private String getStringField(FormDataVo vo, String field) {
        try {
            FieldDataVo fieldData = vo.getFieldData(field);
            return fieldData.getStringValue();
        }catch (Exception e) {

            return null;
        }
    }
}