package com.seeyon.apps.src_flowIntegration.service;

import cn.hutool.log.Log;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.addressbook.manager.AddressBookCustomerFieldInfoManager;
import com.seeyon.apps.addressbook.po.AddressBook;
import com.seeyon.apps.src_flowIntegration.config.FlowIntegrationConfigProvider;
import com.seeyon.apps.src_flowIntegration.constants.FlowIntegrationConstants;
import com.seeyon.apps.src_flowIntegration.dao.SrcFlowDao;
import com.seeyon.apps.src_flowIntegration.listener.FlowEventListener;
import com.seeyon.apps.src_flowIntegration.util.AddressBookUtil;
import com.seeyon.apps.src_flowIntegration.util.FieldUtil;
import com.seeyon.apps.src_flowIntegration.util.TransitionAffairUtil;
import com.seeyon.ctp.common.ctpenumnew.manager.EnumManager;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumItem;
import com.seeyon.ctp.organization.bo.*;
import com.seeyon.ctp.organization.manager.OrgManager;
import org.springframework.beans.factory.annotation.Autowired;
import www.seeyon.com.utils.StringUtil;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class OaFlowQueryService {

    private static Log log = Log.get(FlowEventListener.class);

    @Autowired
    private FlowIntegrationConfigProvider configProvider;
    @Inject
    private SrcFlowDao srcFlowDao;
    @Inject
    private OrgManager orgManager;
    @Inject
    private AddressBookCustomerFieldInfoManager addressBookCustomerFieldInfoManager;
    @Inject
    private EnumManager enumManagerNew;

    /**
     * 通过第三方相关数据查询对应流程ColSummary相关数据
     * @param thirdpartyCode  第三个系统标识
     * @param templateCode  流程表单编码
     * @param thirdFlowId  第三个系统流程表单ID
     * @return  数据库map对象，主要数据来源于col_summary字段信息
     */
    public Map<String,String> getColSummaryData(String thirdpartyCode,String templateCode,String thirdFlowId){
//        先根据流程表单编码字段查询流程表单信息
//        在通过流程表单信息查询当前流程表中唯一值字段及数据库表单名称
//        在通过第三方系统编码和流程表单ID字段查询对应的流程表单数据ID
//        在通过流程表单数据ID查询当前数据的summaryId信息
//        查询流程表单ID
        String formAppid = srcFlowDao.getFormIdByTemplateCode(templateCode);
//        查询流程表单字段信息
        String fieldInfo = srcFlowDao.getFieldInfoByFormId(formAppid);
        JSONObject fieldJSON = JSONObject.parseObject(fieldInfo);
        JSONObject frontFormmain = fieldJSON.getJSONObject("front_formmain");
//        获取需要查询到的数据库字段
        String tableName = frontFormmain.getString("tableName");
        String thirdpartyCodeName = FieldUtil.isDisplayExists(frontFormmain,"第三方系统标识");
        String thirdFlowIdName = FieldUtil.isDisplayExists(frontFormmain,"第三方系统流程ID");
//        查询对应数据唯一值 String tableName,String[] fieldNames,Map<String,String> params
//        设置查询字段
        String[] fieldNames = {"id"};
//        设置查询参数信息
        Map<String,String> whereString = new HashMap<>();
        whereString.put(thirdpartyCodeName,thirdpartyCode);
        whereString.put(thirdFlowIdName,thirdFlowId);
        List<Map<String,Object>> formDatas = srcFlowDao.getFormDataByParam(tableName,fieldNames,whereString);
        String formDataId = "";
        if(formDatas.size()==1){
            Map<String,Object> formData = formDatas.get(0);
            formDataId = formData.get("id")==null?"":formData.get("id").toString();
        }
//        通过数据ID查询对应流程表单查询到一应colSummary数据库信息，通过process_id查询col_summary数据库表信息。
        Map<String,String> colSummary = srcFlowDao.getColSummaryByFormRecordid(formDataId);
        return colSummary;

    }

    /**
     *通过summaryId查询ctp_affair数据获取待办待办列表信息
     * @param summaryId
     * @return
     */
    public JSONArray getTodoList(String summaryId) throws BusinessException {
//        获取系统内置参数第三方系统主数据字段信息
        String extAttrLabel = configProvider.getBizConfigByKey(FlowIntegrationConstants.extAttrLabel);
        JSONArray todoList = new JSONArray();
//        通过summaryId查询，查询当前流程个人事项信息
        List<Map<String,String>> ctpAffairs =  srcFlowDao.getCtpAffairBySummaryId(summaryId);
        for (Map<String,String> ctpAffairMap :ctpAffairs){
            String state = ctpAffairMap.get("state");
            if("3".equals(state)){
                String memberId = ctpAffairMap.get("memberId");
                if(StringUtil.isNotEmpty(memberId)){
                    V3xOrgMember v3xOrgMember = orgManager.getMemberById(Long.parseLong(memberId));
                    AddressBook memberAddressBook = addressBookCustomerFieldInfoManager.getByMemberId(v3xOrgMember.getId());
                    if(null == memberAddressBook) {
                        log.info("人员自定义数据未维护，无法单点登录！");
                        continue;
                    }
                    JSONObject addressBookjson = AddressBookUtil.appleAddressBook(memberAddressBook,enumManagerNew);
//                    通过字段名称查询人员账号主数据数据库字段
                    String extAttrName = srcFlowDao.getMetadataNameByLabel(extAttrLabel);
                    String extAttrValue = addressBookjson.getString(extAttrName);
                    log.info("查询对应人员账号"+extAttrValue);
                    if(StringUtil.isEmpty(extAttrValue)){
                        log.info(extAttrLabel+"未维护，无法单点登录！");
                        continue;
                    }
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("affairName","");
                    jsonObject.put("affairMember",v3xOrgMember.getName());
                    jsonObject.put("affairMemberLoginName",v3xOrgMember.getLoginName());
                    jsonObject.put("affairMemberthirdPartyLoginName",extAttrValue);
                    jsonObject.put("affairStatus","3");
                    jsonObject.put("affairStatusTxt","待办");
                    todoList.add(jsonObject);
                }
            }
        }
        return todoList;
    }

    /**
     *通过processId查询ctp_process_log数据获取待办待办列表信息
     * @param processId
     * @return
     */
    public JSONArray getCompletedList(String processId) throws BusinessException {
//        获取系统内置参数第三方系统主数据字段信息
        String extAttrLabel = configProvider.getBizConfigByKey(FlowIntegrationConstants.extAttrLabel);
        JSONArray completedList = new JSONArray();
        List<Map<String,String>> processLogs = srcFlowDao.getProcessLogsByProcessId(processId);
        for(Map<String,String> processLogMap : processLogs){
            String actionId = processLogMap.get("actionId");
            if(StringUtil.isNotEmpty(actionId)){
                String actionUserId = processLogMap.get("actionUserId");
                if(StringUtil.isNotEmpty(actionUserId)){
                    V3xOrgMember v3xOrgMember = orgManager.getMemberById(Long.parseLong(actionUserId));
                    AddressBook memberAddressBook = addressBookCustomerFieldInfoManager.getByMemberId(v3xOrgMember.getId());
                    if(null == memberAddressBook) {
                        log.info("人员自定义数据未维护，无法单点登录！");
                        continue;
                    }
                    JSONObject addressBookjson = AddressBookUtil.appleAddressBook(memberAddressBook,enumManagerNew);
//                    通过字段名称查询人员账号主数据数据库字段
                    String extAttrName = srcFlowDao.getMetadataNameByLabel(extAttrLabel);
                    String extAttrValue = addressBookjson.getString(extAttrName);
                    log.info("查询对应人员账号"+extAttrValue);
                    if(StringUtil.isEmpty(extAttrValue)){
                        log.info(extAttrLabel+"未维护，无法单点登录！");
                        continue;
                    }

                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("affairName","");
                    jsonObject.put("affairMember",v3xOrgMember.getName());
                    jsonObject.put("affairMemberLoginName",v3xOrgMember.getLoginName());
                    jsonObject.put("affairMemberthirdPartyLoginName",extAttrValue);
//                    获取的都是待办信息，只有待办信息进行输出
                    jsonObject.put("affairStatus", TransitionAffairUtil.actionIdTransitionAffairStatus(actionId));
                    jsonObject.put("affairStatusTxt", TransitionAffairUtil.actionIdTransitionAffairStatusTxt(actionId));
                    jsonObject.put("completeTime",processLogMap.get("actionTime"));
                    jsonObject.put("isLatest",true);
                    completedList.add(jsonObject);
                }
            }
        }
        return completedList;
    }

    /**
     *通过summaryId查询当前表单的数据设置封装数据
     * @param summaryId
     * @return
     */
    public JSONObject getFlowInfo(String summaryId){
        JSONObject flowInfo = new JSONObject();
//        通过sumnmary查询流程参数信息
        Map<String,Object> colSummary = srcFlowDao.getColSummaryById(summaryId);
        String state = colSummary.get("state")==null?"":colSummary.get("state").toString();
        flowInfo.put("flowStatus",TransitionAffairUtil.colSummaryStateFlowState(state));
        flowInfo.put("flowStatusTxt",TransitionAffairUtil.colSummaryStateFlowStateTxt(state));
        return flowInfo;
    }

    /**
     * 通过summaryId对应表单的数据，并且封装成指定格式刷数据
     * @param colSummary
     * @return
     */
    public JSONObject getFormInfo(Map<String,String> colSummary) throws BusinessException {
//        根据formAppid查询字段参数信息
        String fieldInfoStr = srcFlowDao.getFieldInfoByFormId(String.valueOf(colSummary.get("form_appid")));
        JSONObject fieldInfoJson = JSONObject.parseObject(fieldInfoStr);
//        检索字段信息，将数据查询完成并封装数据
//        查询主表表单名称
        JSONObject frontFormmain = fieldInfoJson.getJSONObject("front_formmain");
        String formmainName = frontFormmain.getString("tableName");
        log.info("formmainName:"+formmainName);
        JSONArray fieldInfo = frontFormmain.getJSONArray("fieldInfo");
//        整理主表字段
        List<String> fieldNames = new ArrayList<>();
        for(int i = 0 ; i < fieldInfo.size();i++){
            JSONObject field =  fieldInfo.getJSONObject(i);
            String fieldName = field.getString("name");
            if("排序号".equals(field.getString("display"))){
                continue;
            }
            fieldNames.add(fieldName);
        }
        String[] fieldNameString = fieldNames.toArray(new String[fieldNames.size()]);
        log.info("fieldNameString:"+fieldNameString.toString());
        Map<String,String> formmainParam = new HashMap<>();
        String formmainId = colSummary.get("form_recordid")==null?"":String.valueOf(colSummary.get("form_recordid"));
        formmainParam.put("id",formmainId);
        log.info("formmainId:"+formmainId);
        List<Map<String,Object>> formmainDatas = srcFlowDao.getFormDataByParam(formmainName,fieldNameString,formmainParam);
        Map<String,Object> formmainData = formmainDatas.get(0);
//        设置主表字段
        JSONObject masterTable = toMasterTable(formmainName,fieldInfo,formmainData);
        log.info("masterTable:"+masterTable);
//        查询从表表单数据
        JSONArray formsons = fieldInfoJson.getJSONArray("formsons");
        JSONObject subTables = new JSONObject();
        for(int i = 0 ; i < formsons.size() ;i++){
            JSONObject formson = formsons.getJSONObject(i);
            String formsonName = formson.getString("tableName");
//            整理明细明细表字段
            List<String> subFieldNames = new ArrayList<>();
            JSONArray subFieldInfo = formson.getJSONArray("fieldInfo");
            for(int n = 0 ; n < subFieldInfo.size();n++){
                JSONObject field =  subFieldInfo.getJSONObject(n);
                String subFieldName = field.getString("name");
                if("排序号".equals(field.getString("display"))){
                    continue;
                }
                subFieldNames.add(subFieldName);
            }
            String[] subFieldNameString = subFieldNames.toArray(new String[subFieldNames.size()]);

            Map<String,String> formsonParam = new HashMap<>();
            formsonParam.put("formmain_id",formmainId);
            log.info("formsonParam:"+formsonParam+"formsonName:"+formsonName);
            List<Map<String,Object>> formsonDatas = srcFlowDao.getFormDataByParam(formsonName,subFieldNameString,formsonParam);
//            设置从表数据
            JSONObject subTable = toSubTable(formsonName,subFieldInfo,formsonDatas);
            subTables.putAll(subTable);
        }

        JSONObject formInfo = new JSONObject();
//        保存主表字段数据
        formInfo.put("masterTable",masterTable);
//        保存从表字段数据
        formInfo.put("subTables",subTables);

        return formInfo;
    }

    private JSONObject toMasterTable(String masterTableName,JSONArray fieldInfo,Map<String,Object> formmainData) throws BusinessException {
        JSONObject masterTable = new JSONObject();
        JSONArray masterFieldData = new JSONArray();
//        遍历主表所有字段
        for(int i = 0 ; i < fieldInfo.size();i++){
            JSONObject fieldInfoData = fieldInfo.getJSONObject(i);
            String fieldName = fieldInfoData.getString("name");
            JSONObject mainFieldData = new JSONObject();
            mainFieldData.put("name",fieldName);
            mainFieldData.put("display",fieldInfoData.get("display"));
            log.info("显示名称"+fieldInfoData.get("display"));
            mainFieldData.put("value",formmainData.get(fieldName));
//            判断字段类型，如果字段类型是附件则跳过当前字段
            if("image".equals(fieldInfoData.getString("type"))||"attachment".equals(fieldInfoData.getString("type"))){
                continue;
            }else if ("account".equals(fieldInfoData.getString("type"))){
                if(formmainData.get(fieldName)!=null){
                    V3xOrgAccount v3xOrgAccount = orgManager.getAccountById(Long.parseLong(formmainData.get(fieldName).toString()));
                    mainFieldData.put("showvalue",v3xOrgAccount==null?"":v3xOrgAccount.getName());
                }else{
                    continue;
                }
            }else if ("department".equals(fieldInfoData.getString("type"))){
                if(formmainData.get(fieldName)!=null){
                    V3xOrgDepartment v3xOrgDepartment = orgManager.getDepartmentById(Long.parseLong(formmainData.get(fieldName).toString()));
                    mainFieldData.put("showvalue",v3xOrgDepartment==null?"":v3xOrgDepartment.getName());
                }else{
                    continue;
                }
            }else if ("member".equals(fieldInfoData.getString("type"))){
                if(formmainData.get(fieldName)!=null){
                    V3xOrgMember v3xOrgMember = orgManager.getMemberById(Long.parseLong(formmainData.get(fieldName).toString()));
                    mainFieldData.put("showvalue",v3xOrgMember==null?"":v3xOrgMember.getName());
                }else{
                    continue;
                }
            }else if ("post".equals(fieldInfoData.getString("type"))){
                if(formmainData.get(fieldName)!=null){
                    V3xOrgPost v3xOrgPost = orgManager.getPostById(Long.parseLong(formmainData.get(fieldName).toString()));
                    mainFieldData.put("showvalue",v3xOrgPost==null?"":v3xOrgPost.getName());
                }else{
                    continue;
                }
            }else if ("level".equals(fieldInfoData.getString("type"))){
                if(formmainData.get(fieldName)!=null){
                    V3xOrgLevel v3xOrgLevel = orgManager.getLevelById(Long.parseLong(formmainData.get(fieldName).toString()));
                    mainFieldData.put("showvalue",v3xOrgLevel==null?"":v3xOrgLevel.getName());
                }else{
                    continue;
                }
            }else if ("multiselect".equals(fieldInfoData.getString("type"))){
//                下拉多选
                if(formmainData.get(fieldName)!=null){
                    String value = String.valueOf(formmainData.get(fieldName));
                    String[] values = value.split(",");
                    StringBuilder showvalue = new StringBuilder();
                    for(int n = 0 ; n < values.length;n++){
                        CtpEnumItem ctpEnumItem = enumManagerNew.getCtpEnumItem(Long.parseLong(value));
                        if(ctpEnumItem!=null){
                            showvalue.append(ctpEnumItem.getShowvalue()).append(',');
                        }
                    }
                    if(showvalue.length()>0){
                        showvalue.deleteCharAt(showvalue.length() - 1);
                        formmainData.put("showvalue",showvalue.toString());
                    }else{
                        continue;
                    }
                }else{
                    continue;
                }
            }else if ("select".equals(fieldInfoData.getString("type"))){
//                下拉单选
                if(formmainData.get(fieldName)!=null){
                    String value = String.valueOf(formmainData.get(fieldName));
                    CtpEnumItem ctpEnumItem = enumManagerNew.getCtpEnumItem(Long.parseLong(value));
                    if(ctpEnumItem!=null){
                        formmainData.put("showvalue",ctpEnumItem.getShowvalue());
                    }else{
                        continue;
                    }
                }else{
                    continue;
                }
            }else{
                if(formmainData.get(fieldName)!=null){
                    mainFieldData.put("showvalue",formmainData.get(fieldName));
                }else{
                    continue;
                }
            }
            masterFieldData.add(mainFieldData);
        }
        masterTable.put(masterTableName,masterFieldData);

        return masterTable;
    }

    private JSONObject toSubTable(String formsonName,JSONArray subFieldInfo,List<Map<String,Object>> formsonDatas) throws BusinessException {
//        创建返回值信息
        JSONArray subFieldData = new JSONArray();
        for(Map<String,Object> formsonData :formsonDatas){
            JSONArray formsonDataRow = new JSONArray();
            for(int i = 0 ; i < subFieldInfo.size();i++){
                JSONObject fieldData = new JSONObject();
//                获取当前需要处理的字段
                JSONObject subField = subFieldInfo.getJSONObject(i);
                String fieldName = subField.getString("name");

                fieldData.put("name",fieldName);
                fieldData.put("display",subField.getString("display"));
                fieldData.put("value",formsonData.get(subField.getString("name"))==null?"":formsonData.get(subField.getString("name")));
                if("image".equals(subField.getString("type"))||"attachment".equals(subField.getString("type"))){
                    continue;
                }else if ("account".equals(subField.getString("type"))){
                    if(formsonData.get(fieldName)!=null){
                        V3xOrgAccount v3xOrgAccount = orgManager.getAccountById(Long.parseLong(formsonData.get(fieldName).toString()));
                        fieldData.put("showvalue",v3xOrgAccount==null?"":v3xOrgAccount.getName());
                    }else{
                        continue;
                    }
                }else if ("department".equals(subField.getString("type"))){
                    if(formsonData.get(fieldName)!=null){
                        V3xOrgDepartment v3xOrgDepartment = orgManager.getDepartmentById(Long.parseLong(formsonData.get(fieldName).toString()));
                        fieldData.put("showvalue",v3xOrgDepartment==null?"":v3xOrgDepartment.getName());
                    }else{
                        continue;
                    }
                }else if ("member".equals(subField.getString("type"))){
                    if(formsonData.get(fieldName)!=null){
                        V3xOrgMember v3xOrgMember = orgManager.getMemberById(Long.parseLong(formsonData.get(fieldName).toString()));
                        fieldData.put("showvalue",v3xOrgMember==null?"":v3xOrgMember.getName());
                    }else{
                        continue;
                    }
                }else if ("post".equals(subField.getString("type"))){
                    if(formsonData.get(fieldName)!=null){
                        V3xOrgPost v3xOrgPost = orgManager.getPostById(Long.parseLong(formsonData.get(fieldName).toString()));
                        fieldData.put("showvalue",v3xOrgPost==null?"":v3xOrgPost.getName());
                    }else{
                        continue;
                    }
                }else if ("level".equals(subField.getString("type"))){
                    if(formsonData.get(fieldName)!=null){
                        V3xOrgLevel v3xOrgLevel = orgManager.getLevelById(Long.parseLong(formsonData.get(fieldName).toString()));
                        fieldData.put("showvalue",v3xOrgLevel==null?"":v3xOrgLevel.getName());
                    }else{
                        continue;
                    }
                }else if ("multiselect".equals(subField.getString("type"))){
//                    下拉多选
                    if(formsonData.get(fieldName)!=null){
                        String value = String.valueOf(formsonData.get(fieldName));
                        String[] values = value.split(",");
                        StringBuilder showvalue = new StringBuilder();
                        for(int n = 0 ; n < values.length;n++){
                            CtpEnumItem ctpEnumItem = enumManagerNew.getCtpEnumItem(Long.parseLong(values[n]));
                            if(ctpEnumItem!=null){
                                showvalue.append(ctpEnumItem.getShowvalue()).append(',');
                            }
                        }
                        if(showvalue.length()>0){
                            showvalue.deleteCharAt(showvalue.length() - 1);
                            fieldData.put("showvalue",showvalue.toString());
                        }else{
                            continue;
                        }
                    }else{
                        continue;
                    }
                }else if ("select".equals(subField.getString("type"))){
//                    下拉单选
                    if(formsonData.get(fieldName)!=null){
                        String value = String.valueOf(formsonData.get(fieldName));
                        CtpEnumItem ctpEnumItem = enumManagerNew.getCtpEnumItem(Long.parseLong(value));
                        if(ctpEnumItem!=null){
                            fieldData.put("showvalue",ctpEnumItem.getShowvalue());
                        }else{
                            continue;
                        }
                    }else{
                        continue;
                    }
                }else{
                    if(formsonData.get(fieldName)!=null){
                        fieldData.put("showvalue",formsonData.get(fieldName));
                    }else{
                        continue;
                    }
                }
                formsonDataRow.add(fieldData);
            }
            subFieldData.add(formsonDataRow);
        }
        JSONObject subTable = new JSONObject();
        subTable.put(formsonName,subFieldData);
        return subTable;
    }

}
