package com.engine.htsc.subcompany.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.core.impl.Service;
import com.engine.htsc.subcompany.dao.UfZgssplDao;
import com.engine.htsc.subcompany.model.ReportSequenceVO;
import com.engine.htsc.subcompany.model.UfZgsspl;
import com.engine.htsc.subcompany.model.ZgsDept;
import com.engine.htsc.subcompany.model.ZgsUser;
import com.engine.htsc.subcompany.service.SubCompanyLinkService;
import com.engine.htsc.subcompany.tools.UfzgsServiceTools;
import com.engine.htsc.subcompany.tools.UfzgsplModelTools;
import com.engine.integration.util.StringUtils;
import weaver.general.Util;
import weaver.interfaces.htsc.GlobatTools.JAVATools;

import java.util.*;

public class SubCompanyLinkServiceImpl extends Service implements SubCompanyLinkService {

    protected UfZgssplDao ufZgssplDao = new UfZgssplDao();
    protected UfzgsplModelTools ufzgsplModelTools = new UfzgsplModelTools();
    protected UfzgsServiceTools ufzgsServiceTools = new UfzgsServiceTools();

    /**
     * 审批链主题方法获取参数
     * @param map
     * @return
     */
    public JSONObject getSubCompanySpl(Map<String,Object> map) {
        String unnumber = map.get("unnumber").toString();
        String unnumbercode = map.get("unnumbercode").toString();
        //获取所需要的传参
        List<Map<String,String>> req = (List<Map<String,String>>) JSONArray.parse(map.get("reqMapList").toString());
        //数据库匹配获取对应需要的入参
        List<String> zdmcList = ufZgssplDao.getUfzgssplGx(unnumber);
        List<Map<String,String>> reqMapList = new ArrayList<>();
        for (Map<String,String> mapReq : req){
            HashMap<String,String> mapR = new HashMap<>();
            for (String str : zdmcList){
                mapR.put(str, Util.null2String(mapReq.get(str)));
            }
            reqMapList.add(mapR);
        }
        //获取未去重的审批链
        List<ReportSequenceVO> respListBefore = this.getReportVO(unnumbercode, reqMapList);
        //业务层面去重
        respListBefore = this.removeDuplicateBusiness(respListBefore);
        //系统层面去重
        Map mapRes = this.removeDuplicateCommon(respListBefore);
        //打印日志
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(mapRes);
        JAVATools.writelog("所有数据相加并去重:"+ jsonObject.toJSONString());
        JAVATools.writelog("使用审批链id:"+ Util.null2String(mapRes.get("reportSequenceId")));
        JAVATools.writelog("费用确认:"+ Util.null2String(mapRes.get("fyqr")));
        JAVATools.writelog("会签部门负责人:"+ Util.null2String(mapRes.get("hqbmfzr")));
        JAVATools.writelog("项目负责人（联合投行项目特有）:"+ Util.null2String(mapRes.get("xmfzr")));
        JAVATools.writelog("直接上级审核（香港特有）:"+ Util.null2String(mapRes.get("zjsjsh")));
        JAVATools.writelog("分公司二级部门负责人:"+ Util.null2String(mapRes.get("ejbmfzr")));
        JAVATools.writelog("投行区域负责人（联合投行等二级部特有）:"+ Util.null2String(mapRes.get("thqyfzr")));
        JAVATools.writelog("一级部门负责人:"+ Util.null2String(mapRes.get("yjbmfzr")));
        JAVATools.writelog("项目所属部门负责人:"+ Util.null2String(mapRes.get("xmssbmfzr")));
        JAVATools.writelog("费用岗审核:"+ Util.null2String(mapRes.get("fyg")));
        JAVATools.writelog("财务中心会计:"+ Util.null2String(mapRes.get("kj")));
        JAVATools.writelog("财务中心经理:"+ Util.null2String(mapRes.get("cwjl")));
        JAVATools.writelog("固收业务负责人（资管特有）:"+ Util.null2String(mapRes.get("gsywfzr")));
        JAVATools.writelog("费用承担部门负责人（紫金虚拟基金特有）:"+ Util.null2String(mapRes.get("fycdbmfzr")));
        JAVATools.writelog("分管领导:"+ Util.null2String(mapRes.get("fgld")));
        JAVATools.writelog("财务分管领导（联合付款特有）:"+ Util.null2String(mapRes.get("cwfgld")));
        JAVATools.writelog("子公司总经理:"+ Util.null2String(mapRes.get("zgszjl")));
        JAVATools.writelog("总裁（联合特有）:"+ Util.null2String(mapRes.get("zc")));
        JAVATools.writelog("子公司董事长:"+ Util.null2String(mapRes.get("zgsdsz")));
        JAVATools.writelog("会计处理（联合特有）:"+ Util.null2String(mapRes.get("kjcl")));
        JAVATools.writelog("首席运营官:"+ Util.null2String(mapRes.get("sxyyg")));
        JAVATools.writelog("首席执行官:"+ Util.null2String(mapRes.get("sxzxg")));
        JAVATools.writelog("财务中心出纳:"+ Util.null2String(mapRes.get("cwzxcn")));
        JAVATools.writelog("出纳:"+ Util.null2String(mapRes.get("cn")));
        JAVATools.writelog("出纳人员工号:"+ Util.null2String(mapRes.get("cnrygh")));
        JAVATools.writelog("会签部门法律部:"+ Util.null2String(mapRes.get("hqbmflb")));
        JAVATools.writelog("会签部门风险管理部:"+ Util.null2String(mapRes.get("hqbmfxglb")));
        JAVATools.writelog("总部资金管理岗:"+ Util.null2String(mapRes.get("zbzjglg")));
        JAVATools.writelog("总部资金运营部负责人:"+ Util.null2String(mapRes.get("zbzjyybfzr")));
        JAVATools.writelog("集团领导:"+ Util.null2String(mapRes.get("jtld")));
        JAVATools.writelog("首席财务官:"+ Util.null2String(mapRes.get("sxcwg")));
        JAVATools.writelog("预算管理员:"+ Util.null2String(mapRes.get("ysgly")));
        JAVATools.writelog("首席风险官:"+ Util.null2String(mapRes.get("sxfxg")));
        JAVATools.writelog("工会主席:"+ Util.null2String(mapRes.get("ghzx")));
        JAVATools.writelog("财务管理部负责人:"+ Util.null2String(mapRes.get("cwglbfzr")));
        JAVATools.writelog("紫金总经理:"+ Util.null2String(mapRes.get("zjzjl")));
        return jsonObject;
    }

    /**
     * 查询具体审批链
     * [子类建议重写]
     * @param unumbercode
     * @param reqMapList
     * @return
     */
    protected  List<ReportSequenceVO> getReportVO(String unumbercode, List<Map<String,String>> reqMapList) {
        List<ReportSequenceVO> respListBefore = new ArrayList<>();
        for(Map<String,String> mingxiMap : reqMapList) {
            //根据不同业务获取Dao层入参
            Map<String,String> mapReqSql = this.getMapReqSql(unumbercode, mingxiMap);
            //查询初步符合条件的审批链
            List<UfZgsspl> ufFzjgsplList = ufZgssplDao.getUfzgsspl(mapReqSql);
            //条件过滤并赋值
            List<ReportSequenceVO> fzjgsplVoList = ufzgsServiceTools.convertModelToVO(ufFzjgsplList,mingxiMap.get("bxry"),(HashMap)mingxiMap,unumbercode);
            respListBefore.addAll(fzjgsplVoList);
        }
        return respListBefore;
    }

    /**
     * 根据map生成查询审批链的条件map
     * [子类按需重写]
     * @param mapR
     * @return
     */
    protected Map<String,String> getMapReqSql(String unumbercode,Map<String,String> mapR) {
        HashMap<String,String> mapReqSql = new HashMap<>();
        ZgsUser zgsUser = new ZgsUser(mapR.get("bxry"));
        String cxsprjs = ufzgsplModelTools.getUfzgsJobGrade(mapR.get("bxry"));
        mapReqSql.put("cxspr","bxry");//查询审批人
        mapReqSql.put("cxsprjs",cxsprjs);//查询审批人角色
        mapReqSql.put("sslc",unumbercode);//查询所属流程
        mapReqSql.put("userCode","WK_" + zgsUser.getWorkCode());//直接使用人员Code进行匹配
        return mapReqSql;
    }

    /**
     * 业务层面去重 即不同审批环节的保留哪个置空哪个，业务层面去重
     *  [子类建议重写]
     * @return
     */
    protected List<ReportSequenceVO> removeDuplicateBusiness(List<ReportSequenceVO> rawReportVOList) {
        //单条审批链出现的业务层面的去重
        List<ReportSequenceVO> afterReportVOList = new ArrayList<>();
        //分管领导和总裁董事长和总裁董事长相同则跳过
        for (ReportSequenceVO vo : rawReportVOList) {
            String fgld = vo.getFgld();
            fgld = distinctFgld(fgld,vo.getZc());
            fgld = distinctFgld(fgld,vo.getZgsdsz());
            vo.setFgld(fgld);
            afterReportVOList.add(vo);
        }
        return afterReportVOList;
    }

    /**
     * 相加并去重
     * @param rawReportVOList
     * @return
     */
    protected Map<String, String> removeDuplicateCommon(List<ReportSequenceVO> rawReportVOList) {
        Map<String, String> mapRes = new HashMap<>();
        String reportSequenceId = "";//匹配到的数据库审批链id
        String fyqr = "";//费用确认
        String hqbmfzr = "";//会签部门负责人
        String xmfzr = "";//项目负责人（联合投行项目特有）
        String zjsjsh = "";//直接上级审核（香港特有）
        String ejbmfzr = "";//二级部门负责人 0或空或自定义编码 数据库用来判断是否跳过
        String thqyfzr = "";//投行区域负责人（联合投行等二级部特有）
        String yjbmfzr = "";//一级部门负责人
        String xmssbmfzr = "";//项目所属部门负责人
        String fyg = "";//费用岗审核
        String kj = "";//财务中心会计
        String cwjl = "";//财务中心经理
        String gsywfzr = "";//固收业务负责人（资管特有）
        String fycdbmfzr = "";//费用承担部门负责人（紫金虚拟基金特有）
        String fgld = "";//分管领导
        String cwfgld = "";//财务分管领导（联合付款特有）
        String zgszjl = "";//子公司总经理
        String zc = "";//总裁（联合特有）
        String zgsdsz = "";//子公司董事长
        String kjcl = "";//会计处理（联合特有）
        String cn = "";//出纳（暂定为空）
        String sxyyg = "";//首席运营官
        String sxzxg = "";//首席执行官
        String cwzxcn = "";//财务中心出纳
        String hqbmflb = "";//会签部门法律部
        String hqbmfxglb = "";//会签部门风险管理部
        String zbzjglg = "";//总部资金管理岗
        String zbzjyybfzr = "";//总部资金运营部负责人
        String jtld = "";//集团领导
        String sxcwg = "";//首席财务官
        String ysgly = "";//预算管理员
        String sxfxg = "";//首席风险官
        String ghzx = "";//工会主席
        String cwglbfzr = "";//财务管理部负责人
        String zjzjl = "";//紫金总经理
        //单一节点去重
        for (ReportSequenceVO reportSequenceVO:rawReportVOList){
            reportSequenceId = addIds(reportSequenceId, Util.null2String(reportSequenceVO.getReportSequenceId()));
            fyqr= addIds(fyqr, Util.null2String(reportSequenceVO.getFyqr()));
            xmfzr= addIds(xmfzr, Util.null2String(reportSequenceVO.getXmfzr()));
            zjsjsh= addIds(zjsjsh, Util.null2String(reportSequenceVO.getZjsjsh()));
            ejbmfzr= addIds(ejbmfzr, Util.null2String(reportSequenceVO.getEjbmfzr()));
            thqyfzr= addIds(thqyfzr, Util.null2String(reportSequenceVO.getThqyfzr()));
            yjbmfzr= addIds(yjbmfzr, Util.null2String(reportSequenceVO.getYjbmfzr()));
            xmssbmfzr= addIds(xmssbmfzr, Util.null2String(reportSequenceVO.getXmssbmfzr()));
            fyg = addIds(fyg, Util.null2String(reportSequenceVO.getFyg()));
            kj= addIds(kj, Util.null2String(reportSequenceVO.getKj()));
            cwjl= addIds(cwjl, Util.null2String(reportSequenceVO.getCwjl()));
            gsywfzr= addIds(gsywfzr, Util.null2String(reportSequenceVO.getGsywfzr()));
            fycdbmfzr= addIds(fycdbmfzr, Util.null2String(reportSequenceVO.getFycdbmfzr()));
            fgld= addIds(fgld, Util.null2String(reportSequenceVO.getFgld()));
            cwfgld= addIds(cwfgld, Util.null2String(reportSequenceVO.getCwfgld()));
            zgszjl= addIds(zgszjl, Util.null2String(reportSequenceVO.getZgszjl()));
            zc= addIds(zc, Util.null2String(reportSequenceVO.getZc()));
            zgsdsz= addIds(zgsdsz, Util.null2String(reportSequenceVO.getZgsdsz()));
            kjcl= addIds(kjcl, Util.null2String(reportSequenceVO.getKjcl()));
            cn= addIds(cn, Util.null2String(reportSequenceVO.getCn()));
            sxyyg = addIds(sxyyg, Util.null2String(reportSequenceVO.getSxyyg()));
            sxzxg = addIds(sxzxg, Util.null2String(reportSequenceVO.getSxzxg()));
            cwzxcn = addIds(cwzxcn, Util.null2String(reportSequenceVO.getCwzxcn()));
            hqbmflb = addIds(hqbmflb, Util.null2String(reportSequenceVO.getHqbmflb()));
            hqbmfxglb = addIds(hqbmfxglb, Util.null2String(reportSequenceVO.getHqbmfxglb()));
            zbzjglg = addIds(zbzjglg, Util.null2String(reportSequenceVO.getZbzjglg()));
            zbzjyybfzr = addIds(zbzjyybfzr, Util.null2String(reportSequenceVO.getZbzjyybfzr()));
            jtld = addIds(jtld, Util.null2String(reportSequenceVO.getJtld()));
            sxcwg = addIds(sxcwg, Util.null2String(reportSequenceVO.getSxcwg()));
            hqbmfzr = addIds(hqbmfzr, Util.null2String(reportSequenceVO.getHqbmfzr()));
            ysgly = addIds(ysgly, Util.null2String(reportSequenceVO.getYsgly()));
            sxfxg = addIds(sxfxg, Util.null2String(reportSequenceVO.getSxfxg()));
            ghzx = addIds(ghzx, Util.null2String(reportSequenceVO.getGhzx()));
            zjzjl = addIds(zjzjl, Util.null2String(reportSequenceVO.getZjzjl()));
            cwglbfzr = addIds(cwglbfzr, Util.null2String(reportSequenceVO.getCwglbfzr()));
        }
        mapRes.put("reportSequenceId",reportSequenceId);
        // 费用确认和部门领导的去重逻辑
        fyqr = distinctByCode(fyqr,ejbmfzr);
        fyqr = distinctByCode(fyqr,yjbmfzr);
        fyqr = distinctByCode(fyqr,zgszjl);

        //二级部门负责人和已经部门负责人相同时保留一级部门负责人
        ejbmfzr = distinctByCode(ejbmfzr,yjbmfzr);
        //子公司董事长和总经理去重留董事长
        zgszjl = distinctByCode(zgszjl,zgsdsz);
        //对"紫金公司总经理""紫金公司董事长"节点去重
        zjzjl = distinctByCode(zjzjl,zgsdsz);
        mapRes.put("fyqr",fyqr);
        mapRes.put("hqbmfzr",hqbmfzr);
        mapRes.put("xmfzr",xmfzr);
        mapRes.put("ejbmfzr",ejbmfzr);
        mapRes.put("zjsjsh",zjsjsh);
        mapRes.put("thqyfzr",thqyfzr);
        mapRes.put("yjbmfzr",yjbmfzr);
        mapRes.put("xmssbmfzr",xmssbmfzr);
        mapRes.put("fyg",fyg);
        mapRes.put("kj",kj);
        mapRes.put("cwjl",cwjl);
        mapRes.put("gsywfzr",gsywfzr);
        mapRes.put("fycdbmfzr",fycdbmfzr);
        mapRes.put("fgld",fgld);
        mapRes.put("cwfgld",cwfgld);
        mapRes.put("zgszjl",zgszjl);
        mapRes.put("zc",zc);
        mapRes.put("zgsdsz",zgsdsz);
        mapRes.put("kjcl",kjcl);
        mapRes.put("cn",cn);
        //获取出纳人员工号
        String cnrygh = JAVATools.gethrmidtoworkcode(cn);
        mapRes.put("cnrygh",cnrygh);
        mapRes.put("sxyyg",sxyyg);
        mapRes.put("sxzxg",sxzxg);
        mapRes.put("cwzxcn",cwzxcn);
        mapRes.put("hqbmflb",hqbmflb);
        mapRes.put("hqbmfxglb",hqbmfxglb);
        mapRes.put("zbzjglg",zbzjglg);
        mapRes.put("zbzjyybfzr",zbzjyybfzr);
        mapRes.put("jtld",jtld);
        mapRes.put("sxcwg",sxcwg);
        mapRes.put("ysgly",ysgly);
        mapRes.put("sxfxg",sxfxg);
        mapRes.put("ghzx",ghzx);
        mapRes.put("cwglbfzr",cwglbfzr);
        mapRes.put("zjzjl",zjzjl);
        return mapRes;
    }

    //跨节点去重，分管领导(和总裁董事长相同则跳过）
    private String distinctFgld(String fgld, String zc) {
        String result = "";
        List<Map<String,String>> mapListE = ufZgssplDao.getUserMap(fgld);
        Map<String,String> fgldMap = mapListE.get(1);//分管领导
        List<Map<String,String>> mapListF = ufZgssplDao.getUserMap(zc);
        Map<String, String> zcMap = mapListF.get(1);//总裁，董事长
        for(String code:fgldMap.keySet()){
            if(null==zcMap.get(code)||"".equals(zcMap.get(code))){
                result+=result==""? Util.null2String(fgldMap.get(code)):","+ Util.null2String(fgldMap.get(code));
            }
        }
        return result;
    }
    //数组前后去重,返回param中base不包含的数据
    public String distinctString(String param,String base){
        String result = "";
        if (null!=base&&!"".equals(base)){
            List<String> baseArray = Arrays.asList(base.split(","));
            if (null!=param&&!"".equals(param)){
                List<String> paramArray = Arrays.asList(param.split(","));
                for (String str:paramArray){
                    if (!baseArray.contains(str)){
                        result+=result==""?str:","+str;
                    }
                }
            }
        }else {
            result = param;
        }
        return result;
    }
    //跨界点使用code去重，去除param中包含base的部分
    private String distinctByCode(String param, String base) {
        String result = "";
        if (!"".equals(param)){
            List<Map<String,String>> baseMapList = ufZgssplDao.getUserMap(base);
            Map<String,String> baseMap = baseMapList.get(1);//parm
            List<Map<String,String>> paramMapList = ufZgssplDao.getUserMap(param);
            Map<String, String> paramMap = paramMapList.get(1);//base
            //遍历paramMap，判断baseMap是否存在paramMap中的key值，若不存在则放入结果返回
            for(String code:paramMap.keySet()){
                if(null==baseMap.get(code)||"".equals(baseMap.get(code))){
                    result+=result==""? Util.null2String(paramMap.get(code)):","+ Util.null2String(paramMap.get(code));
                }
            }
        }
        return result;
    }

    public String addIds(String ids,String value){
        if(value==null||"".equals(value)){
            List idArray = new ArrayList(Arrays.asList(ids.split(",")));
            HashSet idSet = new HashSet(idArray);
            ids = String.join(",", idSet);
            return ids;
        }
        if(ids==null||"".equals(ids)){
            List valueArray = new ArrayList(Arrays.asList(value.split(",")));
            HashSet valueSet = new HashSet(valueArray);
            value = String.join(",", valueSet);
            return value;
        }
        List idArray = new ArrayList(Arrays.asList(ids.split(",")));
        List valueArray = new ArrayList(Arrays.asList(value.split(",")));
        idArray.addAll(valueArray);
        HashSet idSet = new HashSet(idArray);
        String str = String.join(",", idSet);
        return str;
    }
}
