package com.seeyon.apps.esign.node;

import com.seeyon.aicloud.common.JsonUtils;
import com.seeyon.apps.collaboration.po.ColSummary;
import com.seeyon.apps.common.workflow.node.ACommonSuperNode;
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.OrgInfo;
import com.seeyon.apps.esign.po.signer.PersonInfo;
import com.seeyon.apps.esign.po.signer.SignParty;
import com.seeyon.apps.esign.po.signer.SignerType;
import com.seeyon.apps.esign.service.ContractCreateService;
import com.seeyon.apps.esign.service.SealService;
import com.seeyon.apps.esign.service.TokenCacheManager;
import com.seeyon.apps.ext.workflow.vo.FieldDataVo;
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
import com.seeyon.apps.ext.workflow.vo.SuperNodeContext;
import com.seeyon.cap4.form.bean.FormDataMasterBean;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import com.seeyon.ctp.util.JDBCAgent;
import com.seeyon.utils.form.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

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


public class EsignOneSignerNode extends ACommonSuperNode {

    private static final Log log = LogFactory.getLog(EsignOneSignerNode.class);

    private TokenCacheManager tokenCacheManager = (TokenCacheManager) AppContext.getBean("tokenCacheManager");
    private EsignConfigProvider configProvider = EsignConfigProvider.getInstance();
    private ContractCreateService contractCreateService = (ContractCreateService) AppContext.getBean("contractCreateService");
    private SealService sealService = (SealService) AppContext.getBean("sealService");

    @Override
    public String getPluginId() {
        return EsignConfigConstants.getPluginId();
    }

    @Override
    public String getFormParse() {
        return "";
    }

    @Override
    public SuperNodeContext proceed(String s, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) {
        SuperNodeContext context = new SuperNodeContext();
        context.setNeedSave(true);
        log.info("进入 E签宝单方签署集成超级节点");

        try {
            FlowParamSource source = new FlowParamSource();
            source.setConfigProvider(configProvider);
            source.setFormDataVo(formDataVo);
            source.setDoAutoSign(false);
            String isFixAppUnit = configProvider.getBizConfigByKey(EsignConfigConstants.FIXAPPUNIT);
            String unitName = null;
            if("true".equals(isFixAppUnit)){
                unitName = configProvider.getBizConfigByKey(EsignConfigConstants.FIXAPPUNITNAME);
            }else {
                unitName = getStringField(formDataVo,"签订单位");
            }
            String appId = tokenCacheManager.getAppIdByOrgName(unitName);
            source.setSignerParties(buildSigners(appId,formDataVo,false,getStringField(formDataVo,"签订单位")));
            source.setAppId(appId);
            source.setMasterBean(formDataMasterBean);
            String esignFlowId = contractCreateService.startSign(source);
            if(esignFlowId == null) {
                return context.back("E签宝签署发起失败");
            }
            log.info("E签宝签署流程ID: " + esignFlowId + " , OA超级节点ID：" + formDataVo.getToken());
            log.info("E签宝单方签署合同已发送: " + esignFlowId);
            formDataVo.getNewFieldDataMap().put("电子签合同流程ID", esignFlowId);
            return context.wait("等待签署结束");
        } catch (Exception e) {
            log.error("E签宝签署失败", e);
            e.printStackTrace();
            context.setErrMsg("E签宝签署失败: " + e.getMessage());
            return context.back("E签宝签署失败: " + e.getMessage());
        }
    }

    @Override
    public String getNodeId() {
        return "nd_20250702";
    }

    @Override
    public String getNodeName() {
        return "E签宝甲方单方签署节点";
    }

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

    private String getPsnName(FormDataVo formDataVo) throws NoSuchFieldException {
        OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");
        FieldDataVo psn = formDataVo.getFieldData("甲方签署经办人");
        String psnName = null;
        if(psn != null) {
            try {
                V3xOrgMember member = orgManager.getMemberById(Long.parseLong((String)psn.getDbValue()));
                psnName = member.getName();
            }catch (Exception e){

            }
        }
        return psnName;
    }

    private List<SignParty> buildSigners(String appId,FormDataVo formDataVo, Boolean doAutoSign, String orgName) throws NoSuchFieldException, BusinessException {
        List<SignParty> parties = new ArrayList<>();
        SignParty aParty = new SignParty();
        aParty.setPartyId("甲方");
        aParty.setSignOrder(2);
        aParty.setSignerType(SignerType.ORG);
        aParty.setAutoSign(doAutoSign);
        aParty.setSealId(getStringField(formDataVo,"选择甲方印章"));
        OrgInfo orgInfo = new OrgInfo();
        orgInfo.setOrgName(orgName);
        aParty.setOrgInfo(orgInfo);
        if(!doAutoSign){
            String psnName = getPsnName(formDataVo);
            if(psnName == null) {
                throw new RuntimeException("甲方签署经办人为空");
            }
            String psnMobile = getStringField(formDataVo,"甲方签署经办人联系方式");
            PersonInfo personInfo = new PersonInfo();
            personInfo.setName(psnName);
            personInfo.setPhone(psnMobile);
            orgInfo.setTransactor(personInfo);
            FieldDataVo isLpSign = formDataVo.getFieldData("是否盖法人章");
            if(isLpSign != null && "是".equals(isLpSign)) {
                SignParty lpParty = new SignParty();
                lpParty.setPartyId("法人章");
                lpParty.setAutoSign(false);
                lpParty.setSignOrder(3);
                lpParty.setSignerType(SignerType.LP);
                parties.add(lpParty);
            }
        }
        parties.add(aParty);
        String signWay = getStringField(formDataVo, "签署方式");
        String signWayText = null;
        try {
            signWayText = EnumMapUtils.getEnumShowValue(signWay);
        }catch (Exception e) {}
        if(!"甲方线上，乙方线下".equals(signWayText)){
            SignParty bParty = new SignParty();
            bParty.setPartyId("乙方");
            bParty.setSignOrder(1);
            try {
                String bSignerType = formDataVo.getFieldData("乙方签署类型").getStringValue();
                if(!"组织".equals(bSignerType)) {
                    PersonInfo bPersonInfo = new PersonInfo();
                    bPersonInfo.setPhone(getStringField(formDataVo,"乙方电话"));
                    bPersonInfo.setName(getStringField(formDataVo,"乙方姓名"));
                    bParty.setPersonInfo(bPersonInfo);
                    bParty.setSignerType(SignerType.PERSON);
                }else {
                    OrgInfo bOrgInfo = new OrgInfo();
                    bOrgInfo.setLegalName(getStringField(formDataVo,"乙方法人姓名"));
                    bOrgInfo.setOrgName(getStringField(formDataVo,"乙方单位名称"));
                    bOrgInfo.setOrgCode(getStringField(formDataVo,"乙方统一社会信用代码"));
                    bOrgInfo.setLegalIdCardNo(getStringField(formDataVo,"乙方法人身份证号"));
                    PersonInfo transactor = new PersonInfo();
                    transactor.setName(getStringField(formDataVo,"乙方经办人姓名"));
                    transactor.setIdCardNo(getStringField(formDataVo,"乙方经办人身份证号"));
                    transactor.setPhone(getStringField(formDataVo,"乙方经办人手机号"));
                    bOrgInfo.setTransactor(transactor);
                    bParty.setOrgInfo(bOrgInfo);
                    bParty.setSignerType(SignerType.ORG);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            parties.add(bParty);
        }
        buildAntiFakeSigner(orgName,parties,formDataVo,doAutoSign);
        return parties;
    }

    private String getLastSenderId(Long caseId) {
        List<String> columns = new ArrayList<>();
        columns.add("sender_id");
        SqlBuildParam param = new SqlBuildParam();
        List<FormWhereCondition> conditions = new ArrayList<>();
        conditions.add(FormWhereCondition.build().fieldName("CASE_ID").value(caseId));
        param.setSqlType(SqlType.SELECT);
        param.setTableName("ctp_affair");
        param.setQueryColumns(columns);
        param.setConditions(conditions);
        param.setPageNo(1);
        param.setPageSize(1);
        param.setOrderField("UPDATE_DATE");
        param.setSortType("DESC");
        Map<String, Object> sqlMap = FormTableExecutor.generateSql(param);
        JDBCAgent agent = new JDBCAgent();
        try {
            agent.execute((String)sqlMap.get("sql"), (List)sqlMap.get("params"));
            log.info("执行sql为: " + sqlMap.get("sql"));
            List<Map<String, Object>> rows = agent.resultSetToList();
            if(rows.size() <= 0) {
                return null;
            }
            Map<String, Object> map = rows.get(0);
            return (String)map.get("SENDER_ID");
        } catch (Exception e) {
            log.error("执行sql为: " + sqlMap.get("sql"));
            log.error("执行sql参数为: " + JsonUtils.toJSONString(sqlMap.get("params")));
            log.error(e.getMessage(), e);
        } finally {
            agent.close();
        }

        return null;
    }

    private V3xOrgMember getPsn(Long memberId) throws NoSuchFieldException {
        OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");
        if(memberId != null) {
            try {
                V3xOrgMember member = orgManager.getMemberById(memberId);
                return member;
            }catch (Exception e){

            }
        }
        return null;
    }

    private void buildAntiFakeSigner(String orgName,List<SignParty> parties,FormDataVo formDataVo,Boolean doAutoSign) throws NoSuchFieldException, BusinessException {;
        String enableAntiFakeSign = configProvider.getBizConfigByKey(EsignConfigConstants.ENABLEANTIFAKESIGN);
        if(!"true".equals(enableAntiFakeSign)) {
            return;
        }
        SignParty party = new SignParty();
        ColSummary colSummary = formDataVo.getColSummary();
        Long caseId = colSummary.getCaseId();
        String senderId = getLastSenderId(caseId);
        party.setPartyId("防伪章签署方");
        party.setSignOrder(2);
        party.setSignerType(SignerType.ORG);
        party.setAutoSign(doAutoSign);
        OrgInfo orgInfo = new OrgInfo();
        party.setOrgInfo(orgInfo);
        String isFixAppUnitName = configProvider.getBizConfigByKey(EsignConfigConstants.FIXAPPUNIT);
        String unitName = "true".equals(isFixAppUnitName) ? configProvider.getBizConfigByKey(EsignConfigConstants.FIXAPPUNITNAME) : orgName;
        party.setSealId(sealService.getAntiFakeSealId(unitName));
        if(!doAutoSign){
            V3xOrgMember psn = getPsn(Long.parseLong(senderId));
            orgInfo.setOrgName(unitName);
            String psnName = psn.getName();
            if(psnName == null) {
                throw new RuntimeException("防伪章签署经办人为空");
            }
            String psnMobile = psn.getTelNumber();
            PersonInfo personInfo = new PersonInfo();
            personInfo.setName(psnName);
            personInfo.setPhone(psnMobile);
            orgInfo.setTransactor(personInfo);
        }else {
            orgInfo.setOrgId(tokenCacheManager.getOrgIdByOrgName(unitName));
        }
        parties.add(party);
    }
}
