package com.jeeplus.modules.sg.managementcenter.projectPlanArrage.service;

import com.google.common.collect.Maps;
import com.jeeplus.common.utils.DateUtils;
import com.jeeplus.common.utils.SpringContextHolder;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.common.websocket.service.system.SystemInfoSocketHandler;
import com.jeeplus.core.service.CrudService;
import com.jeeplus.modules.act.entity.Act;
import com.jeeplus.modules.act.mapper.ActMapper;
import com.jeeplus.modules.act.service.ActProcessService;
import com.jeeplus.modules.act.service.ActTaskService;
import com.jeeplus.modules.oa.entity.OaNotify;
import com.jeeplus.modules.oa.entity.OaNotifyMaterial;
import com.jeeplus.modules.oa.entity.OaNotifyRecord;
import com.jeeplus.modules.oa.mapper.OaNotifyMapper;
import com.jeeplus.modules.oa.mapper.OaNotifyRecordMapper;
import com.jeeplus.modules.oa.service.OaNotifyService;
import com.jeeplus.modules.sg.managementcenter.projectPlanArrage.entity.ProjectActProcIns;
import com.jeeplus.modules.sg.managementcenter.projectPlanArrage.entity.ProjectActProclnsAss;
import com.jeeplus.modules.sg.managementcenter.projectPlanArrage.entity.ProjectPlanArrage;
import com.jeeplus.modules.sg.managementcenter.projectPlanArrage.mapper.ProjectPlanActMapper;
import com.jeeplus.modules.sg.managementcenter.projectPlanArrage.util.PackagingUtil;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletContext;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Transactional(readOnly = true)
public class ProjectPlanActService{
    @Autowired
    private ProjectPlanActMapper projectPlanActMapper;
    @Autowired
    private ActMapper actMapper;
    @Autowired
    private ProcessEngineFactoryBean processEngine;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private ActProcessService actProcessService;
    @Autowired
    private ActTaskService actTaskService;
    @Autowired
    private OaNotifyService oaNotifyService;
    @Autowired
    private OaNotifyRecordMapper oaNotifyRecordMapper;
    @Autowired
    private OaNotifyMapper oaNotifyMapper;

    //查询配网项目经理当前安排的计划
    public List<ProjectActProclnsAss> findListAss(ProjectActProclnsAss projectActProclnsAss){
        return projectPlanActMapper.findListAss(projectActProclnsAss);
    }

    //启动工作流流程
    @Transactional(readOnly = false)
    public void startProjectArrangeAct(List<ProjectPlanArrage> projectPlanArrages){
        ProjectActProcIns projectActProcIns = new ProjectActProcIns();
        projectActProcIns.preInsert();
        projectActProcIns.setCustomId("0");//初始状态为完成
        projectPlanActMapper.processAct(projectActProcIns);//保存

        String procDefKey="jhap";//流程定义KEY
        String businessTable="xm_project_arrange_procIns";//业务表表名
        String businessId="0739e9eafe034e05930c4202e6368b9d";//业务表编号
        //根据key获取最大版本的版本号
        String procDefId = projectPlanActMapper.actModelId(procDefKey);
        //启动流程
        ProcessDefinition p = actProcessService.getProcessDefinition(procDefId);
        //定义Map
        Map<String, Object> vars = Maps.newHashMap();
        //流程标题
        String title=UserUtils.getUser().getName()+ "在" + DateUtils.getDateTime() + "发起" + p.getName();//流程标题，显示在待办任务标题
        List<String> personName = getPersonName(projectPlanArrages, "1");//获取施工单位项目经理集合
        getConsMaps(vars,personName);
        startProcessConsProject(procDefKey,businessTable,businessId,title,vars,projectActProcIns,projectPlanArrages);
        List<String> strings = new ArrayList<String>();
        for (ProjectPlanArrage planArrage:projectPlanArrages){
            if (null!=planArrage.getProjectName()&&!"".equals(planArrage.getProjectName())){
                strings.add(planArrage.getProjectName());
            }
        }
        projectPlanActMapper.updateMaterialNetProject(strings);
    }
    public void getConsMaps(Map<String, Object> vars,List<String> personName){
        int len = personName.size();
        String cons = "";
        String constructionManager = "";
        boolean flag = false;
        for (int i = 1; i <= 20; i++) {
            flag = false;
            cons = "cons"+i;
            if (i-1<len){
                flag = true;
            }
            vars.put(cons,flag);
        }
        int count = 1;
        for (String ct:personName){
            constructionManager = "constructionManager"+count;
            vars.put(constructionManager,UserUtils.getByUserName(ct).getLoginName());
            count++;
        }
    }

    @Transactional(readOnly = false)
    public void startProcessConsProject(String procDefKey, String businessTable, String businessId, String title, Map<String, Object> vars,ProjectActProcIns projectActProcIns,List<ProjectPlanArrage> projectPlanArrages) {
        // 设置流程变量
        if (vars == null) {
            vars = Maps.newHashMap();
        }

        String userId = (String) vars.get("applyUserId");
        if (userId == null) {
            userId = UserUtils.getUser().getLoginName();
        }
        String userName = UserUtils.getByLoginName(userId).getName();
        vars.put("userName", userName);

        // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
        identityService.setAuthenticatedUserId(userId);

        // 设置流程标题
        if (StringUtils.isNotBlank(title)) {
            vars.put("title", title);
        }

        // 启动流程
        ProcessInstance procIns = runtimeService.startProcessInstanceByKey(procDefKey, businessTable + ":" + businessId, vars);
        Act act = new Act();
        act.setBusinessTable(businessTable);// 业务表名
        act.setBusinessId(projectActProcIns.getId());    // 业务表ID
        act.setProcInsId(procIns.getId());
        act.setVars(vars);
        actMapper.updateProcInsIdByBusinessId(act);
        // 更新业务表流程实例ID
        List<ProjectActProclnsAss> projectActProclnsAss = getProjectActProclnsAss(projectPlanArrages, procIns.getId());
        projectPlanActMapper.insertProcInsAssList(projectActProclnsAss);
    }

    //获取不同执行人:施工单位项目经理  施工单位项目经理1 配网项目经理 2 运行单位项目经理 3
    public List<String> getPersonName(List<ProjectPlanArrage> projectPlanArrages,String str){
        HashSet<String> hashSet = new HashSet<String>();
        for (ProjectPlanArrage planArrage:projectPlanArrages){
            if (str.equals("1")){//施工单位项目经理  = 1
                if (null!=planArrage.getConstructionUnit()&&!"".equals(planArrage.getConstructionUnit())){
                    hashSet.add(planArrage.getConstructionUnit());
                }
            }
            if (str.equals("2")){//配网项目经理  = 1
                if (null!=planArrage.getDistributionNetwork()&&!"".equals(planArrage.getDistributionNetwork())){
                    hashSet.add(planArrage.getDistributionNetwork());
                }
            }
            if (str.equals("3")){//运行单位项目经理  = 1
                if (null!=planArrage.getOperationUnit()&&!"".equals(planArrage.getOperationUnit())){
                    hashSet.add(planArrage.getOperationUnit());
                }
            }

        }
        List<String> stringList = new ArrayList<String>();
        for (String s :hashSet){
            stringList.add(s);
        }
        return stringList;
    }

    //替换类
    public List<ProjectActProclnsAss> getProjectActProclnsAss(List<ProjectPlanArrage> projectPlanArrages,String procInsId){
        List<ProjectActProclnsAss> projectActProclnsAsses = new ArrayList<ProjectActProclnsAss>();
        ProjectActProclnsAss projectActProclnsAss = null;
        for (ProjectPlanArrage planArrage:projectPlanArrages){
            projectActProclnsAss = new ProjectActProclnsAss();
            projectActProclnsAss.preInsert();
            projectActProclnsAss.setProcInsId(procInsId);
            projectActProclnsAss.setCustomId("0");
            projectActProclnsAss.setRemarks(planArrage.getRemarks());//发起人备注
            projectActProclnsAss.setProjectName(planArrage.getProjectName());
            projectActProclnsAss.setProjectNumber(planArrage.getProjectNumber());
            projectActProclnsAss.setProjectLine(planArrage.getProjectLine());
            projectActProclnsAss.setProjectPowerRange(planArrage.getProjectPowerRange());
            projectActProclnsAss.setProjectSwitch(planArrage.getProjectSwitch());
            projectActProclnsAss.setProjectMonthDate(planArrage.getProjectMonthDate());
            projectActProclnsAss.setProjectDate(planArrage.getProjectDate());
            projectActProclnsAss.setProjectPowerOut(planArrage.getProjectPowerOut());
            projectActProclnsAss.setStatus("0");
            projectActProclnsAss.setDistributionNetwork(planArrage.getDistributionNetwork());
            projectActProclnsAss.setConstructionUnit(planArrage.getConstructionUnit());
            projectActProclnsAss.setOperationUnit(planArrage.getOperationUnit());
            projectActProclnsAss.setBackToStauts("0");
            projectActProclnsAss.setAssociatedBag(planArrage.getAssociatedBag());
            projectActProclnsAss.setAssociatedSort(planArrage.getAssociatedSort());
            projectActProclnsAss.setPowerPackage(planArrage.getPowerPackage());
            projectActProclnsAss.setPowerPackageSort(planArrage.getPowerPackageSort());
            projectActProclnsAsses.add(projectActProclnsAss);
        }
        return projectActProclnsAsses;
    }

    /**
     * 生成随机数
     * @return
     */
    public String getStatus(){
        int machineId = 1;
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if (hashCodeV<0){
            hashCodeV=-hashCodeV;
        }
        return  (machineId+String.format("%015d",hashCodeV));
    }


    //获取当前的项目定义号
    public String getMapProjectId(List<ProjectActProclnsAss> listAss){
        String str = "";
        for (ProjectActProclnsAss proclnsAss:listAss){
            if (null!=proclnsAss.getProjectName()&&!"".equals(proclnsAss.getProjectName())&&null!=proclnsAss.getProjectNumber()&&!"".equals(proclnsAss.getProjectNumber())){
                str+=proclnsAss.getProjectNumber()+",";
            }
        }
        str = str.substring(0,str.length()-1);
        return str;
    }

    //得到安排计划月份
    public Date getMouthDate(List<ProjectActProclnsAss> listAss){
        Date date = new Date();
        for (ProjectActProclnsAss proclnsAss:listAss){
            if (null!=proclnsAss.getProjectMonthDate()&&!"".equals(proclnsAss.getProjectMonthDate())){
                date = proclnsAss.getProjectMonthDate();
                break;
            }
        }
        return date;
    }

    //得到安排计划月份
    public String getProjectPowerOut(List<ProjectActProclnsAss> listAss){
        String string = "停电";
        for (ProjectActProclnsAss proclnsAss:listAss){
            if (null!=proclnsAss.getProjectPowerOut()&&!"".equals(proclnsAss.getProjectPowerOut())){
                string = proclnsAss.getProjectPowerOut();
                break;
            }
        }
        return string;
    }


    //提取月份日期
    public Date getProjectMonthDate(List<ProjectActProclnsAss> listAss){
        Date date = null;
        for (ProjectActProclnsAss proclnsAss:listAss){
            date = proclnsAss.getProjectMonthDate();
            break;
        }
        return date;
    }

    //汇总,获取最终集合--施工单位项目经理
    public List<ProjectPlanArrage> getSummaryService(List<ProjectPlanArrage> projectPlanArrages,List<ProjectActProclnsAss> projectActProclnsAsses){
        String name = UserUtils.getUser().getName();//获取当前操作人
        for (ProjectActProclnsAss proclnsAss:projectActProclnsAsses){
            for (ProjectPlanArrage planArrage:projectPlanArrages){
                if (planArrage.getProjectName().equals(proclnsAss.getProjectName())&&planArrage.getProjectNumber().equals(proclnsAss.getProjectNumber())){
                    planArrage.setProjectMonthDate(proclnsAss.getProjectMonthDate());
                    planArrage.setProjectDate(proclnsAss.getProjectDate());
                    planArrage.setBackToStauts(proclnsAss.getBackToStauts());
                    planArrage.setBackToText(proclnsAss.getBackToText());
                    planArrage.setConstructionUnit(proclnsAss.getConstructionUnit());
                    planArrage.setProjectPowerOut(proclnsAss.getProjectPowerOut());
                    planArrage.setAssociatedBag(proclnsAss.getAssociatedBag());
                    planArrage.setAssociatedSort(proclnsAss.getAssociatedSort());
                    planArrage.setPowerPackage(proclnsAss.getPowerPackage());
                    planArrage.setPowerPackageSort(proclnsAss.getPowerPackageSort());
                    planArrage.setRemarks(proclnsAss.getRemarks());
                    if (proclnsAss.getConstructionUnit().equals(name)){
                        planArrage.setOperationStatus("0");//允许操作
                    }else {
                        planArrage.setOperationStatus("1");//不允许操作
                    }
                    break;
                }
            }
        }
        return projectPlanArrages;
    }

    //汇总,获取最终集合--配网项目经理
    public List<ProjectPlanArrage> getNetworkService(List<ProjectPlanArrage> projectPlanArrages,List<ProjectActProclnsAss> projectActProclnsAsses){
        for (ProjectActProclnsAss proclnsAss:projectActProclnsAsses){
            for (ProjectPlanArrage planArrage:projectPlanArrages){
                if (planArrage.getProjectName().equals(proclnsAss.getProjectName())&&planArrage.getProjectNumber().equals(proclnsAss.getProjectNumber())){
                    planArrage.setProjectMonthDate(proclnsAss.getProjectMonthDate());
                    planArrage.setProjectDate(proclnsAss.getProjectDate());
                    planArrage.setBackToStauts(proclnsAss.getBackToStauts());
                    planArrage.setBackToText(proclnsAss.getBackToText());
                    planArrage.setConstructionUnit(proclnsAss.getConstructionUnit());
                    planArrage.setProjectPowerOut(proclnsAss.getProjectPowerOut());
                    planArrage.setAssociatedBag(proclnsAss.getAssociatedBag());
                    planArrage.setAssociatedSort(proclnsAss.getAssociatedSort());
                    planArrage.setPowerPackage(proclnsAss.getPowerPackage());
                    planArrage.setPowerPackageSort(proclnsAss.getPowerPackageSort());
                    planArrage.setRemarks(proclnsAss.getRemarks());
                    break;
                }
            }
        }
        return projectPlanArrages;
    }

    //验证当前自己操作的项目时间为空的判断---施工单位项目经理
    public boolean getJudgePlanTimeNULL(List<ProjectPlanArrage> projectPlanArrages){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        boolean flag = false;
        String name = UserUtils.getUser().getName();
        for (ProjectPlanArrage planArrage:projectPlanArrages){
            //得到计划安排的项目
            if (planArrage.getWhetherStatus().equals("0")&&planArrage.getArrageFlag().equals("1")){
                if (name.equals(planArrage.getConstructionUnit())){
                    if (null==planArrage.getProjectDate()){
                        flag = true;
                        break;
                    }
                }
            }
        }
        return flag;
    }

    //验证时间集合时间不一致--施工单位项目项目经理
    public boolean getJudgePlanTimeService(List<ProjectPlanArrage> projectPlanArrages){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        boolean flag = false;
        List<ProjectPlanArrage> projectPlanArrageList = new ArrayList<ProjectPlanArrage>();
        for (ProjectPlanArrage plan:projectPlanArrages){
            if (plan.getArrageFlag().equals("1")){
                if (null!=plan.getPowerPackage()&&!"".equals(plan.getPowerPackage())){
                    projectPlanArrageList.add(plan);
                }
            }
        }
        //存放停电包 hashSet
        HashSet<String> hashSets = new HashSet<String>();
        for (ProjectPlanArrage projectPack:projectPlanArrageList){
            hashSets.add(projectPack.getPowerPackage());//添加至停电包集合
        }
        //循环判断hashSet
        HashSet<String> packHashSet = new HashSet<String>();
        for (String str:hashSets){
            packHashSet = new HashSet<String>();
            for (ProjectPlanArrage pa:projectPlanArrageList){
                if (str.equals(pa.getPowerPackage())){
                    if (null!=pa.getProjectDate()){
                        packHashSet.add(sdf.format(pa.getProjectDate()));
                    }
                }
            }
            if (packHashSet.size()>1){
                flag = true;
                return flag;
            }
        }



//        HashSet<String> stringHashSet = new HashSet<String>();
//        for (ProjectPlanArrage planArrage:projectPlanArrages){
//            flag = false;
//            //如果时间不为空
//            if (null!=planArrage.getProjectDate()){
//                stringHashSet = new HashSet<String>();
//                PackagingUtil.getSplice(planArrage.getProjectPowerRange(),stringHashSet);
//                for (ProjectPlanArrage planArrage1:projectPlanArrageList){
//                    if (null!=planArrage1.getProjectDate()){
//                        for (String s:stringHashSet){
//                            if (planArrage1.getProjectPowerRange().contains(s)){
//                                if (!sdf.format(planArrage.getProjectDate()).equals(sdf.format(planArrage1.getProjectDate()))){
//                                    flag = true;
//                                    break;
//                                }
//                            }
//                        }
//                    }
//                    if (flag){
//                        break;
//                    }
//                }
//            }
//            if (flag){
//                break;
//            }
//        }
        return  flag;
    }

    //施工单位项目 经理 向配网项目经理发送流程
    @Transactional(readOnly = false)
    public void conRunProInsId(Act act,List<ProjectPlanArrage> projectPlans,List<ProjectPlanArrage> presentActProInsAss){
        // 设置意见
        act.setComment(("yes".equals(act.getFlag()) ? "[同意] " : "[驳回] ") + act.getComment());
        act.preUpdate();
        // 对不同环节的业务逻辑进行操作
        String taskDefKey = act.getTaskDefKey();
        // 提交流程任务
        Map<String, Object> vars = Maps.newHashMap();
        String admin = UserUtils.getByUserName("肖文和").getLoginName();
        vars.put("disManager",admin);
        actTaskService.complete(act.getTaskId(), act.getProcInsId(), act.getComment(), vars);
        //业务 处理保存 流程表
        //获取流程id
        String procInsId = act.getProcInsId();
        String name = UserUtils.getUser().getName();//获取当前登录名
        //得到所有安排计划的项目
        List<ProjectActProclnsAss> projectActProcInsAssList = PackagingUtil.getProjectActProcInsAssList(projectPlans, procInsId);
        ProjectActProclnsAss proclnsAss = new ProjectActProclnsAss();
        proclnsAss.setProcInsId(procInsId);
        proclnsAss.setConstructionUnit(name);
        projectPlanActMapper.deleteConsAss(proclnsAss);
        projectPlanActMapper.insertProcInsAssList(projectActProcInsAssList);
    }


    //配网项目 经理 向运行单位人员发送流程
    @Transactional(readOnly = false)
    public void newWorkRunProInsId(Act act,List<ProjectPlanArrage> projectPlans){
        // 设置意见
        act.setComment(("yes".equals(act.getFlag()) ? "[同意] " : "[驳回] ") + act.getComment());
        act.preUpdate();
        // 对不同环节的业务逻辑进行操作
        String taskDefKey = act.getTaskDefKey();
        //获取人
        List<String> personName = getPersonName(projectPlans, "3");//获取运行单位人员
        //获取运行单位集合
        String ids = "";
        for (String s:personName){
            ids+=UserUtils.getByUserName(s).getId()+",";
        }
        if (ids.contains(",")){
            ids = ids.substring(0,ids.length()-1);
        }
        // 提交流程任务
        Map<String, Object> vars = Maps.newHashMap();
//        getRunsMaps(vars,personName);
        actTaskService.complete(act.getTaskId(), act.getProcInsId(), act.getComment(), vars);
        //业务 处理保存 流程表
        //获取流程id
        String procInsId = act.getProcInsId();
        ProjectActProclnsAss procNet = new ProjectActProclnsAss();
        procNet.setProcInsId(procInsId);
        //删除
        projectPlanActMapper.deleteNetAss(procNet);
        List<ProjectActProclnsAss> netList = PackagingUtil.getNetList(projectPlans, procInsId);
        OaNotify oaNotify = new OaNotify();
        int count = 0;
        oaNotify.setType("9");
        oaNotify.setTitle("项目计划安排通知");
        oaNotify.setContent("请在详情中查看...");
        oaNotify.setStatus("1");
        oaNotify.setOaNotifyRecordIds(ids);
        oaNotifyService.saveListProjectArrage(oaNotify,netList);
        projectPlanActMapper.insertProcInsAssList(netList);//保存流程表

        List<String> strings = new ArrayList<String>();
        for (ProjectActProclnsAss proclnsAss:netList){
            if (null!=proclnsAss.getProjectName()&&!"".equals(proclnsAss.getProjectName())){
                strings.add(proclnsAss.getProjectName());
            }
        }
        projectPlanActMapper.updateMaterialProject(strings);
        List<OaNotifyRecord> list = oaNotify.getOaNotifyRecordList();
        for(OaNotifyRecord o : list){
            count++;
            //发送通知到客户端
            ServletContext context = SpringContextHolder
                    .getBean(ServletContext.class);
            new SystemInfoSocketHandler().sendMessageToUser(UserUtils.get(o.getUser().getId()).getLoginName(), "收到一条新通知，请到我的通知查看！");
        }
    }

    public void getRunsMaps(Map<String, Object> vars,List<String> personName){
        int len = personName.size();
        String cons = "";
        String constructionManager = "";
        boolean flag = false;
        for (int i = 1; i <= 20; i++) {
            flag = false;
            cons = "runs"+i;
            if (i-1<len){
                flag = true;
            }
            vars.put(cons,flag);
        }
        int count = 1;
        for (String ct:personName){
            constructionManager = "runPerson"+count;
            vars.put(constructionManager,UserUtils.getByUserName(ct).getLoginName());
            count++;
        }
    }


    //配网项目 经理 向运行单位人员发送流程
    @Transactional(readOnly = false)
    public void runListRunProInsId(Act act){
        // 设置意见
        act.setComment(("yes".equals(act.getFlag()) ? "[同意] " : "[驳回] ") + act.getComment());
        act.preUpdate();
        // 对不同环节的业务逻辑进行操作
        String taskDefKey = act.getTaskDefKey();
        // 提交流程任务
        Map<String, Object> vars = Maps.newHashMap();
//        String admin = UserUtils.getByUserName("李云龙").getLoginName();
        vars.put("disManager2","xiaowh");
        actTaskService.complete(act.getTaskId(), act.getProcInsId(), act.getComment(), vars);
    }

    //配网项目 经理 ---结束流程
    @Transactional(readOnly = false)
    public void disList2ProInsId(Act act,List<ProjectActProclnsAss> listAss){
        // 设置意见
        act.setComment(("yes".equals(act.getFlag()) ? "[同意] " : "[驳回] ") + act.getComment());
        act.preUpdate();
        // 对不同环节的业务逻辑进行操作
        String taskDefKey = act.getTaskDefKey();
        // 提交流程任务
        Map<String, Object> vars = Maps.newHashMap();
        actTaskService.complete(act.getTaskId(), act.getProcInsId(), act.getComment(), vars);
        //获取项目名称
        List<String> strings = new ArrayList<String>();
        for (ProjectActProclnsAss proclnsAss:listAss){
            if (null!=proclnsAss.getProjectName()&&!"".equals(proclnsAss.getProjectName())){
                strings.add(proclnsAss.getProjectName());
            }
        }
        projectPlanActMapper.updateMaterialProject(strings);
    }
}
