package com.engine.jucailinkq.attendance.component.calendarscheduling.service.impl;

import com.cloudstore.eccom.constant.WeaBoolAttr;
import com.cloudstore.eccom.pc.table.WeaTable;
import com.cloudstore.eccom.pc.table.WeaTableColumn;
import com.cloudstore.eccom.pc.table.WeaTableType;
import com.cloudstore.eccom.result.WeaResultMsg;
import com.engine.jucailinkq.attendance.component.calendarscheduling.service.WorkRulesService;
import com.engine.jucailinkq.attendance.component.persongroup.cmd.GetDatatableRecurrenceCmd;
import com.engine.jucailinkq.attendance.component.persongroup.commonutil.PersongroupCommonUtil;
import com.engine.jucailinkq.attendance.enums.CheckBoxEnum;
import com.engine.jucailinkq.attendance.enums.PersonGroupListTypeEnum;
import com.engine.jucailinkq.attendance.enums.RegularScheduleTypeEnum;
import com.engine.jucailinkq.common.exception.AttendanceRunTimeException;
import com.engine.jucailinkq.common.util.CommonUtil;
import com.engine.jucailinkq.common.util.DateUtil;
import com.engine.jucailinkq.common.util.DbTools;
import com.engine.jucailinkq.common.util.Utils;
import com.engine.core.impl.Service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import weaver.general.BaseBean;
import weaver.general.PageIdConst;
import weaver.general.TimeUtil;
import weaver.general.Util;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author liang.cheng
 * @Date 2023/12/26 6:54 PM
 * @Description: TODO
 * @Version 1.0
 */
@Slf4j
public class WorkRulesServiceImpl extends Service implements WorkRulesService {

    private  Map<String,Object> departMentMap = PersongroupCommonUtil.getDepartMent();
    private  Map<String,Object> subCompanyMap = PersongroupCommonUtil.getSubCompany();
    private  Map<String,String> classesInformationMap = PersongroupCommonUtil.getClassesAndSimpleNameInformation();
    @Override
    public Map<String, Object> getWorkRulesList(String resourceIds) {
        Map<String, Object> resultMap = new HashMap<>(4);
        log.debug("getWorkRulesList : [{}]",resourceIds);
        String modeId = Utils.getFormmodeIdMap().get("uf_jcl_kq_bcxx");
        Set<String> bcids = Sets.newHashSet();
        for (String resourceId :resourceIds.split(",")){
            bcids.addAll(CommonUtil.getAllDataIds(resourceId,modeId,DateUtil.getCurrentDate()));
        }
        WeaTable table = new WeaTable();
        String pageId = "936b04850b7b478cafd59d1cf4cb9fc1";
        table.setPageID(pageId);
        table.setPageUID(String.format("%s_%s",pageId,user.getUID()));
        String pageSize = PageIdConst.getPageSize(pageId, user.getUID());
        table.setPagesize(pageSize);
        String fields = "t.id, t.mc,t.jc,t.ys,t.bcsdxx";
        table.setBackfields(fields);

        String fromSql = " from uf_jcl_kq_bcxx t ";
        table.setSqlform(fromSql);
        String sqlWhere = " where 1=1 ";
        if (bcids.size() > 0){
            sqlWhere = sqlWhere + " and t.id in ("+String.join(",",bcids)+")";
        }
        sqlWhere = sqlWhere + " or attendance_organization is null";

        table.setSqlwhere(sqlWhere);

        table.setSqlprimarykey("id");
        table.getColumns().add(new WeaTableColumn("id").setDisplay(WeaBoolAttr.FALSE));
        table.getColumns().add(new WeaTableColumn("20%", "班次名称", "mc"));
        table.getColumns().add(new WeaTableColumn("20%", "简称", "jc"));
        table.getColumns().add(new WeaTableColumn("20%", "颜色", "ys"));
        table.getColumns().add(new WeaTableColumn("40%", "班次时间", "bcsdxx"));

        table.setTableType(WeaTableType.RADIO);

        WeaResultMsg result = new WeaResultMsg(false);
        result.putAll(table.makeDataResult());
        result.success();
        resultMap.putAll(result.getResultMap());
        return resultMap;
    }

    @Override
    public Map<String, Object> getDepartSchedule(Map<String, Object> params) {
        Map<String, Object> resultMap = new HashMap<>();
        String dateTime = Util.null2String(params.get("dateTime"));
        int pageSize = Integer.valueOf(Util.null2String(params.get("pageSize")));
        int pageindex = Integer.valueOf(Util.null2String(params.get("pageindex")));
        String deparmentId = Util.null2String(params.get("deparment"));
        String subcompanyId = Util.null2String(params.get("subcompany"));
        String employeeIds = Util.null2String(params.get("employeeIds"));
        String username = Util.null2String(params.get("username"));
        String psersongroup = Util.null2String(params.get("psersongroup"));
        String userId = Util.null2String(user.getUID());

        //0:全体人员、1：分部、2：部门,3:人员
        String type = Util.null2String(params.get("type"));

        String conditions =" 1=1";
        if (!"".equals(subcompanyId)){
            conditions = conditions +" and subcompanyid1="+subcompanyId;
        }
        if (!"".equals(deparmentId)){
            conditions = conditions +" and departmentid="+deparmentId;
        }

        if (!"".equals(username)){
            conditions = conditions +" and lastname like '%"+username+"%'";
        }
        Set<String> psersongroupUserIds = null;
        if (!"".equals(psersongroup)){
            psersongroupUserIds = CommonUtil.getEmpGroupUserIds(psersongroup);
            if (!"".equals(employeeIds)){
                Set<String> ids = Sets.newHashSet();
                for (String employeeId:employeeIds.split(",")){
                    if (psersongroupUserIds.contains(employeeId)){
                        ids.add(employeeId);
                    }
                }
                psersongroupUserIds = ids;
            }
        }else {
            if (!"".equals(employeeIds)){
                conditions = conditions +" and id in ("+employeeIds+")";
            }
        }


        List<Map<String,Object>> dataTable = Lists.newArrayList();
        if (psersongroupUserIds != null && psersongroupUserIds.size()>0){
            String querySql = "select id,subcompanyid1,departmentid,workcode,lastname from hrmresource where "+conditions+" and id in (";
            List<List<String>> userIdPartitions= Lists.partition(Lists.newArrayList(psersongroupUserIds),200);
            for (List<String> userIdPartition :userIdPartitions){
                String sql = querySql+String.join(",",userIdPartition)+")";
                dataTable.addAll(DbTools.getSqlToList(sql));
            }
        }



        int startindex = (pageindex-1)*pageSize;
        int endindex = pageindex*pageSize;
        int monthDays = DateUtil.getDays(dateTime, Calendar.DAY_OF_MONTH);
        String startTime = dateTime+"-01";
        String endTime = dateTime+"-"+monthDays;
        //当为系统管理员用户登录时
        if ("1".equals(userId)){
            if ("".equals(psersongroup)){
                String querySql = "select id,subcompanyid1,departmentid,workcode,lastname from hrmresource ";
                if (!conditions.equals("")){
                    querySql = querySql+" where "+conditions;
                }
                dataTable = DbTools.getSqlToList(querySql);
            }
        }else {
            if ("".equals(psersongroup)){
                String querySql = "select id,subcompanyid1,departmentid,workcode,lastname from hrmresource ";
                if (!conditions.equals("")){
                    querySql = querySql+" where "+conditions;
                }
                dataTable = DbTools.getSqlToList(querySql);
            }

            String sql = "select a.list_type,b.mainid,b.empid,b.filters,b.sqltj,b.bdate,b.edate from uf_ryqz a left join uf_ryqz_dt1 b on a.id=b.mainid  where a.userfor=5 and a.fzgly=?";
            List<Map<String,Object>> personnelGrouping = DbTools.getSqlToList(sql,userId);
            personnelGrouping = personnelGrouping.stream().filter(e -> DateUtil.getTime(endTime).compareTo(DateUtil.getTime(e.get("bdate").toString())) >=0 && (Util.null2String(e.get("edate")).equals("") || DateUtil.getTime(startTime).compareTo(DateUtil.getTime(e.get("edate").toString())) <=0)).collect(Collectors.toList());

            Map<String,String> userIdMap =Maps.newHashMap();
            userIdMap.put(userId,startTime+","+endTime);
            for (Map<String,Object> data:personnelGrouping){
                String empid = Util.null2String(data.get("empid"));
                String filters = Util.null2String(data.get("filters"));
                String list_type = Util.null2String(data.get("list_type"));
                String bdate = Util.null2String(data.get("bdate"));
                String edate = Util.null2String(data.get("edate"));
                String sqltj = Util.null2String(data.get("sqltj"));
                String date = "";
                if (DateUtil.getTime(startTime).compareTo(DateUtil.getTime(bdate)) >= 0){
                    date = startTime;
                }else {
                    date = bdate;
                }
                if (edate.equals("") || DateUtil.getTime(endTime).compareTo(DateUtil.getTime(edate)) <=0){
                    date = date +","+endTime;
                }else if (DateUtil.getTime(endTime).compareTo(DateUtil.getTime(edate)) >0){
                    date = date +","+edate;
                }
                if (PersonGroupListTypeEnum.PERSON.getKey().equals(list_type) && !"".equals(empid)){
                    userIdMap.put(empid,date);
                }else if (PersonGroupListTypeEnum.CONDITION.getKey().equals(list_type) && !"".equals(filters)){
                    filters = filters.replace("ａｎｄ","and");
                    filters = filters.replace("ｏｒ","or");
                    sql = "select id,seclevel from hrmresource where 1=1 ";
                    if (filters.contains("field")){
                        sql = "select a.id from hrmresource a left join cus_fielddata b on a.id=b.id where scope='HrmCustomFieldByInfoType' and "+filters;
                    }else {
                        sql = sql+ " and "+filters;
                    }
                    log.debug("getPersonnelGroupingByPerson filter sql : {}",sql);
                    List<Map<String,Object>> dataList = DbTools.getSqlToList(sql);
                    for (Map<String,Object> dataMap :dataList){
                        String hrmId = Util.null2String(dataMap.get("id"));
                        userIdMap.put(hrmId,date);
                    }
                }else if ("2".equals(list_type) && !"".equals(sqltj)){
                    sqltj = Utils.converSQL(sqltj);
                    log.info("getPersonnelGroupingByPerson sqltj : [{}]",sqltj);
                    List<Map<String,Object>> dataList = DbTools.getSqlToList(sqltj);
                    for (Map<String,Object> dataMap :dataList){
                        String hrmId = Util.null2String(dataMap.get("id"));
                        userIdMap.put(hrmId,date);
                    }
                }
            }

            for (int i=0;i<dataTable.size();i++){
                Map<String,Object> map = dataTable.get(i);
                String id = Util.null2String(map.get("id"));
                if (userIdMap.get(id) == null){
                    dataTable.remove(i);
                    i--;
                }else {
                    map.put("effectTime",userIdMap.get(id));
                }
            }
        }
        int total = dataTable.size();
        resultMap.put("count",total);
        if (endindex > total){
            endindex = total;
        }
        if (startindex < 0){
            startindex = 0;
        }
        dataTable = dataTable.subList(startindex,endindex);


        Map<String,Object> param = Maps.newHashMap();
        param.put("tableName",params.get("tableName"));
        param.put("startDate",startTime);
        param.put("endDate",endTime);
        param.put("pblx","0");
        param.put("current","1");
        param.put("pageSize","31");
        param.put("recurrence","1");

        List<Map<String, Object>> datas = Lists.newArrayList();
        for (Map<String,Object> map:dataTable){
            String id = map.get("id").toString();
            String effectTime = Util.null2String(map.get("effectTime"));
            String startEffectTime = "";
            String endEffectTime = "";
            if (!"".equals(effectTime)){
                startEffectTime = effectTime.split(",")[0];
                endEffectTime = effectTime.split(",")[1];
            }
            Map<String, Object> data = Maps.newHashMap();
            data.put("workcode",map.get("workcode"));
            data.put("resourceId",id);
            data.put("lastname",map.get("lastname"));
            data.put("subcompanyId",map.get("subcompanyid1"));
            data.put("subcompany",subCompanyMap.get(map.get("subcompanyid1")));
            data.put("departmentId",map.get("departmentid"));
            data.put("department",departMentMap.get(map.get("departmentid")));
            param.put("pbdx",id);
            Map<String,Object> result = commandExecutor.execute(new GetDatatableRecurrenceCmd(param));

            List<Map<String, Object>> dataTableList = (List<Map<String, Object>>)result.get("dataTableList");
            dataTableList = Utils.getSchedulingList(dataTableList);
            log.debug("dataTableList : [{}]",dataTableList);
            for (Map<String, Object> scheduleMap :dataTableList){
                String bcrq = Util.null2String(scheduleMap.get("bcrq"));
                String bcxx = Util.null2String(scheduleMap.get("bcxx"));
                if (!"".equals(bcxx)){
                    String[] strArr = classesInformationMap.get(bcxx).split("&");
                    String content = strArr.length>1?strArr[1]:"";
                    String title = strArr.length>0?strArr[0]:"";
                    String color = strArr.length>2?strArr[2]:"";
                    if (!"".equals(effectTime)){
                        if (DateUtil.getTime(bcrq).compareTo(DateUtil.getTime(startEffectTime)) >=0 && DateUtil.getTime(bcrq).compareTo(DateUtil.getTime(endEffectTime)) <=0){
                            data.put(bcrq,new HashMap(){{
                                put("content",content);
                                put("title",title);
                                put("id",bcxx);
                                put("edit",true);
                                put("color",color);
                            }});
                        }else {
                            data.put(bcrq,new HashMap(){{
                                put("content",content);
                                put("title",title);
                                put("id",bcxx);
                                put("edit",false);
                                put("color",color);
                            }});
                        }
                    }else {
                        data.put(bcrq,new HashMap(){{
                            put("content",content);
                            put("title",title);
                            put("id",bcxx);
                            put("edit",true);
                            put("color",color);
                        }});
                    }
                }
            }

            datas.add(data);
        }
        resultMap.put("datas",datas);
        resultMap.put("columns",getCloumns(monthDays,startTime));
        resultMap.put("pagesize",pageSize);

        resultMap.put("pageindex",pageindex);
        return resultMap;
    }

    public List<Map<String,Object>> getCloumns(int monthDays,String startTime){
        BaseBean bb = new BaseBean();
        String numberWidth = bb.getPropValue("jclAttendance", "numberWidth");
        String numberDisplay = bb.getPropValue("jclAttendance", "numberDisplay");
        String nameWidth = bb.getPropValue("jclAttendance", "nameWidth");
        String nameDisplay = bb.getPropValue("jclAttendance", "nameDisplay");
        String subcompantWidth = bb.getPropValue("jclAttendance", "subcompanyWidth");
        String subcompanyDisplay = bb.getPropValue("jclAttendance", "subcompanyDisplay");
        String departmentWidth = bb.getPropValue("jclAttendance", "departmentWidth");
        String departmentDisplay = bb.getPropValue("jclAttendance", "departmentDisplay");
        String classWidth = bb.getPropValue("jclAttendance", "classWidth");

        List<Map<String,Object>> cloumns = Lists.newArrayList();
        cloumns.add(new HashMap(){{
            put("title","编号");
            put("width",numberWidth);
            put("dataIndex","workcode");
            put("key","workcode");
            put("fixed","left");
            put("align","center");
            put("context","编号");
            put("display",numberDisplay);
        }});
        cloumns.add(new HashMap(){{
            put("title","姓名");
            put("width",nameWidth);
            put("dataIndex","lastname");
            put("key","lastname");
            put("fixed","left");
            put("align","center");
            put("display",nameDisplay);
            put("context","姓名");
        }});
        cloumns.add(new HashMap(){{
            put("title","分部");
            put("width",subcompantWidth);
            put("dataIndex","subcompany");
            put("key","subcompany");
            put("fixed","left");
            put("align","center");
            put("display",subcompanyDisplay);
            put("context","分部");
        }});
        cloumns.add(new HashMap(){{
            put("title","部门");
            put("width",departmentWidth);
            put("dataIndex","department");
            put("key","department");
            put("fixed","left");
            put("align","center");
            put("display",departmentDisplay);
            put("context","部门");
        }});

        for (int i=0;i<monthDays;i++){
            Map<String,Object> map = Maps.newHashMap();
            int dayWeek = TimeUtil.getDayOfWeek(DateUtil.AfterDay(startTime,i));
            String titleContext = String.valueOf(i+1);
            if (dayWeek == 0){
                //周日
                titleContext = "<div class=\"dh\" style=\"color: red;\"><div class=\"d\">"+(i+1)+"</div><div class=\"w\">日</div></div>";
            }else if (dayWeek == 1){
                titleContext = "<div class=\"dh\" style=\"color: rgb(0, 0, 0);\"><div class=\"d\">"+(i+1)+"</div><div class=\"w\">一</div></div>";
            }else if (dayWeek == 2){
                titleContext = "<div class=\"dh\" style=\"color: rgb(0, 0, 0);\"><div class=\"d\">"+(i+1)+"</div><div class=\"w\">二</div></div>";
            }else if (dayWeek == 3){
                titleContext = "<div class=\"dh\" style=\"color: rgb(0, 0, 0);\"><div class=\"d\">"+(i+1)+"</div><div class=\"w\">三</div></div>";
            }else if (dayWeek == 4){
                titleContext = "<div class=\"dh\" style=\"color: rgb(0, 0, 0);\"><div class=\"d\">"+(i+1)+"</div><div class=\"w\">四</div></div>";
            }else if (dayWeek == 5){
                titleContext = "<div class=\"dh\" style=\"color: rgb(0, 0, 0);\"><div class=\"d\">"+(i+1)+"</div><div class=\"w\">五</div></div>";
            }else if (dayWeek == 6){
                //周六
                titleContext ="<div class=\"dh\" style=\"color: red;\"><div class=\"d\">"+(i+1)+"</div><div class=\"w\">六</div></div>";
            }
            map.put("context",i+1);
            map.put("title",titleContext);
            map.put("dataIndex",DateUtil.AfterDay(startTime,i));
            map.put("key",i+1);
            map.put("width",classWidth);
            map.put("isCalendar",0);
            map.put("display","true");
            cloumns.add(map);
        }


        return cloumns;
    }

    @Override
    public Map<String, Object> saveCalendarWork(Map<String, Object> params) {
        String bcxxId = Util.null2String(params.get("bcxx"));
        String resourceIds = Util.null2String(params.get("resourceIds"));
        String dateArrs = Util.null2String(params.get("date"));
        Map<String,Object> resultMap = Maps.newHashMap();
        List<String> resourceList = Arrays.asList(resourceIds.split(","));
        List<String> dateList = Arrays.asList(dateArrs.split(","));
        String formmodeid = Utils.getFormmodeIdMap().get("uf_pbjg");
        List<Map<String,Object>> organizationList = Lists.newArrayList();
        String sql = "select id,sfxx,bcsdxx from uf_jcl_kq_bcxx where id = ?";
        List<Map<String,Object>> list = Lists.newArrayList();
        Set<String> userIds = Sets.newHashSet();
        if (!"".equals(bcxxId)){
             list = DbTools.getSqlToList(sql,bcxxId);
        }
        for (String date : dateList){
            //系统管理员
            List<String> beContainIds = null;
            if (user.getUID() == 1){
                beContainIds=resourceList;
            }else {
                beContainIds = getHaveResourceIds(String.valueOf(user.getUID()),resourceList,date);
            }
            //排班结果模块
            for (String str :beContainIds){
                Map<String,Object> map = Maps.newHashMap();
                map.put("dx",str);
                map.put("dxlx", "0");
                map.put("rqlx",CommonUtil.getRqlx(str,date));
                map.put("pbtj",RegularScheduleTypeEnum.CALENDAR.getKey());
                map.put("bcrq",date);
                if ("".equals(bcxxId)){
                    map.put("sfxx",null);
                    map.put("bcsdxx",null);
                    map.put("bcxx",null);
                }else {
                    map.put("sfxx", Util.null2String(list.get(0).get("sfxx")).equals("") ?CheckBoxEnum.UNCHECKED.getValue() : Util.null2String(list.get(0).get("sfxx")));
                    map.put("bcsdxx",list.get(0).get("bcsdxx"));
                    map.put("bcxx",bcxxId);
                }
                map.put("sfdkpp",CheckBoxEnum.UNCHECKED.getKey());
                map.put("pbrq",DateUtil.getCurrentDate());
                map.put("pbsj",DateUtil.getCurrentTime("yyyy-MM-dd HH:mm").split(" ")[1]);
                if (!"".equals(map.get("rqlx"))){
                    organizationList.add(map);
                }else {
                    userIds.add(str);
                }
            }


        }

        /**插入排班结果表*/
        resultMap.put("result",PersongroupCommonUtil.insertSchedulingResults(organizationList,formmodeid));
        if (!(boolean)resultMap.get("result")){
            throw new AttendanceRunTimeException("插入数据失败，请检查修改班次人员是否有对应的企业日历");
        }
        if (userIds.size() > 0){
            throw new AttendanceRunTimeException("部分人员更新失败，请检查修改班次人员是否有对应的企业日历");
        }
        return resultMap;
    }

    /**
     * 该登录用户拥有权限查看以及编辑的用户集合
     * @param userId
     * @param resourceIds 查询出的集合
     * @param date
     * @return
     */
    public List<String> getHaveResourceIds(String userId,List<String> resourceIds,String date){

        String sql = "select a.list_type,b.mainid,b.empid,b.filters,b.bdate,b.edate,b.sqltj from uf_ryqz a left join uf_ryqz_dt1 b on a.id=b.mainid  where a.userfor=5 and a.fzgly=?";
        List<Map<String,Object>> personnelGrouping = DbTools.getSqlToList(sql,userId);
        personnelGrouping = personnelGrouping.stream().filter(e -> DateUtil.getTime(date).compareTo(DateUtil.getTime(e.get("bdate").toString())) >=0 && (Util.null2String(e.get("edate")).equals("") || DateUtil.getTime(date).compareTo(DateUtil.getTime(e.get("edate").toString())) <=0)).collect(Collectors.toList());
        Set<String> userIds = PersongroupCommonUtil.getUserIdsByPersonnelGrouping(personnelGrouping,DateUtil.getCurrentDate());
        userIds.add(userId);
        List<String> beContainIds = Lists.newArrayList();
        for (String resourceId:resourceIds){
            if (userIds.contains(resourceId)){
                beContainIds.add(resourceId);
            }
        }
        log.debug("be contain userIds : [{}]",beContainIds);
        return beContainIds;
    }

    @Override
    public Map<String,Object> queryDefaultCalendar(Map<String, Object> params) {
        Map<String,Object> resultMap = Maps.newHashMap();
        String nd = Util.null2String(params.get("nd"));
        String sql = "select a.rq,a.nlrq,a.mc,b.id from uf_jcl_kq_rlxx a left join uf_jcl_kq_rlmc b on a.rlmc=b.id where nd=?";
        List<Map<String,Object>> dataList = DbTools.getSqlToList(sql,nd);
        String id = "";
        for (Map<String,Object> map:dataList){
            if (!Util.null2String(map.get("id")).equals("")){
                id = Util.null2String(map.get("id"));
            }
        }
        Map<String,List<Map<String,Object>>> dataGroupBy = dataList.stream().collect(Collectors.groupingBy(e->Util.null2String(e.get("id"))));
        resultMap.put("data",dataGroupBy.get(id));
        return resultMap;
    }
}
