package com.engine.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.attendance.component.calendarscheduling.service.WorkRulesService;
import com.engine.attendance.component.persongroup.cmd.GetDatatableRecurrenceCmd;
import com.engine.attendance.component.persongroup.commonutil.PersongroupCommonUtil;
import com.engine.attendance.enums.CheckBoxEnum;
import com.engine.attendance.enums.PersonGroupListTypeEnum;
import com.engine.attendance.enums.RegularScheduleTypeEnum;
import com.engine.common.util.CommonUtil;
import com.engine.common.util.DateUtil;
import com.engine.common.util.DbTools;
import com.engine.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.conn.RecordSet;
import weaver.conn.constant.DBConstant;
import weaver.general.PageIdConst;
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,Object> classesInformationMap = PersongroupCommonUtil.getClassesInformation();
    @Override
    public Map<String, Object> getWorkRulesList(String resourceIds) {
        Map<String, Object> resultMap = new HashMap<>(4);
        log.info("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(),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 and t.id in ("+String.join(",",bcids)+")";
        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 userId = Util.null2String(user.getUID());

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

        String conditions ="";
        if (type.equals("0")){
            conditions = " 1=1 ";
        }else if (type.equals("1")){
            conditions = " subcompanyid1="+subcompanyId;
        }else if (type.equals("2")){
            conditions = " departmentid="+deparmentId;
        }
        RecordSet rs = new RecordSet();
        String dbType = rs.getDBType();
        List<Map<String,Object>> dataTable = null;
        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 ("oracle".equals(dbType) || "dm".equals(dbType) || "jc".equals(dbType) || "st".equals(dbType)){
//                String sql = "select row_number() over(order by id asc) rownum,id from hrmresource where "+conditions;
//                sql = "select top 1 a.id from ( "+sql+" ) a where a.rownum>"+startindex;
//                String queryDatatablesql = "select top "+pageSize+" id,subcompanyid1,departmentid,workcode,lastname from hrmresource where id >=("+sql+") and "+conditions;
//                log.info("queryDatatablesql : {}",queryDatatablesql);
//                dataTable = DbTools.getSqlToList(queryDatatablesql);


                String sql = "select id,subcompanyid1,departmentid,workcode,lastname,ROWNUM rn from hrmresource where 1=1 and ROWNUM<="+endindex;
                sql = sql+" and "+conditions;
                String queryDatatablesql = "select * from ("+sql+") where rn >"+startindex;
                log.info("queryDatatablesql : {}",queryDatatablesql);
                dataTable = DbTools.getSqlToList(queryDatatablesql);

            }else if ("sqlserver".equals(dbType)){
                String sql = "select row_number() over(order by id asc) rownum,id from hrmresource where "+conditions;
                sql = "select top 1 a.id from ( "+sql+" ) a where a.rownum>"+startindex;
                String queryDatatablesql = "select top "+pageSize+" id,subcompanyid1,departmentid,workcode,lastname from hrmresource where id >=("+sql+") and "+conditions;
                log.info("queryDatatablesql : {}",queryDatatablesql);
                dataTable = DbTools.getSqlToList(queryDatatablesql);
            }else {
                String sql = "select id from hrmresource where "+conditions+" limit "+startindex+",1";
                String querySql = "select id,subcompanyid1,departmentid,workcode,lastname from hrmresource where id >=("+sql+") and "+conditions+" limit "+pageSize;
                log.info("queryDatatablesql : {}",querySql);
                dataTable = DbTools.getSqlToList(querySql);
            }
        }else {
            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.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 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 "+conditions;
                    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 scopeid=-1 and "+filters+" and "+conditions;
                    }else {
                        filters = filters.replace("ａｎｄ","and");
                        filters = filters.replace("ｏｒ","or");
                        sql = sql+ " and "+filters;
                    }
                    log.info("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);
                    }
                }
            }

            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));
                }
            }
        }

        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.info("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)){
                    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",classesInformationMap.get(bcxx));
                                put("id",bcxx);
                                put("edit",true);
                            }});
                        }else {
                            data.put(bcrq,new HashMap(){{
                                put("content",classesInformationMap.get(bcxx));
                                put("id",bcxx);
                                put("edit",false);
                            }});
                        }
                    }else {
                        data.put(bcrq,new HashMap(){{
                            put("content",classesInformationMap.get(bcxx));
                            put("id",bcxx);
                            put("edit",true);
                        }});
                    }
                }
            }

            datas.add(data);
        }
        resultMap.put("datas",datas);
        resultMap.put("columns",getCloumns(monthDays,startTime));
        resultMap.put("pagesize",pageSize);
        resultMap.put("count",dataTable.size());
        resultMap.put("pageindex",pageindex);
        return resultMap;
    }

    public List<Map<String,Object>> getCloumns(int monthDays,String startTime){
        List<Map<String,Object>> cloumns = Lists.newArrayList();
        cloumns.add(new HashMap(){{
            put("title","编号");
            put("width",100);
            put("dataIndex","workcode");
            put("key","workcode");
            put("fixed","left");
            put("align","center");
        }});
        cloumns.add(new HashMap(){{
            put("title","姓名");
            put("width",100);
            put("dataIndex","lastname");
            put("key","lastname");
            put("fixed","left");
            put("align","center");
        }});
        cloumns.add(new HashMap(){{
            put("title","分部");
            put("width",150);
            put("dataIndex","subcompany");
            put("key","subcompany");
            put("fixed","left");
            put("align","center");
        }});
        cloumns.add(new HashMap(){{
            put("title","部门");
            put("width",150);
            put("dataIndex","department");
            put("key","department");
            put("fixed","left");
            put("align","center");
        }});

        for (int i=0;i<monthDays;i++){
            Map<String,Object> map = Maps.newHashMap();
            map.put("title",i+1);
            map.put("dataIndex",DateUtil.AfterDay(startTime,i));
            map.put("key",i+1);
            map.put("width",90);
            map.put("isCalendar",0);
            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 date = Util.null2String(params.get("date"));
        Map<String,Object> resultMap = Maps.newHashMap();
        List<String> resourceList = Arrays.asList(resourceIds.split(","));
        //系统管理员
        List<String> beContainIds = null;
        if (user.getUID() == 1){
            beContainIds=resourceList;
        }else {
            beContainIds = getHaveResourceIds(String.valueOf(user.getUID()),resourceList,date);
        }
        //排班结果模块
        String formmodeid = Utils.getFormmodeIdMap().get("uf_pbjg");
        List<Map<String,Object>> organizationList = Lists.newArrayList();
        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));
            organizationList.add(map);
        }
        String sql = "select id,mc,sfxx from uf_jcl_kq_bcxx where id=?";
        List<Map<String,Object>> bcxxList = DbTools.getSqlToList(sql,bcxxId);
        List<Map<String,Object>> insertDataList = Lists.newArrayList();
        Map<String,Object> insertDataMap = Maps.newHashMap();
        insertDataList.add(insertDataMap);
        insertDataMap.put("pbtj",RegularScheduleTypeEnum.CALENDAR.getKey());
        insertDataMap.put("bcrq",date);
        insertDataMap.put("sfxx", bcxxList.get(0).get("sfxx"));
        insertDataMap.put("sfdkpp",CheckBoxEnum.UNCHECKED.getKey());
        insertDataMap.put("bcxx",bcxxId);
        insertDataMap.put("pbrq",DateUtil.getCurrentDate());
        insertDataMap.put("pbsj",DateUtil.getCurrentTime("yyyy-MM-dd HH:mm").split(" ")[1]);

        /**插入排班结果表*/
        resultMap.put("result",PersongroupCommonUtil.insertShiftSchedulingResults(organizationList,insertDataList,formmodeid));
        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 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);
        userIds.add(userId);
        List<String> beContainIds = Lists.newArrayList();
        for (String resourceId:resourceIds){
            if (userIds.contains(resourceId)){
                beContainIds.add(resourceId);
            }
        }
        log.info("be contain userIds : [{}]",beContainIds);
        return beContainIds;
    }
}
