package com.api.customization.qc3189074.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.kq.biz.KQGroupComInfo;
import com.engine.kq.biz.KQShiftManagementComInfo;
import com.engine.kq.biz.KqMembersValidateBiz;
import com.engine.kq.cmd.shiftschedule.SaveShiftScheduleCmd;
import com.engine.kq.log.KQLog;
import weaver.common.DateUtil;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;
import weaver.hrm.resource.ResourceComInfo;
import weaver.systeminfo.SystemEnv;

import java.util.*;

public class CustomScheduleUtil {
    String openKqGroupId = Util.null2String(new BaseBean().getPropValue("qc3189074","openKqGroupId"));//启动新功能的考勤组
   /* List<String> openKqGroupList = Arrays.stream(openKqGroupId.split(","))
            .map(String::trim)
            .collect(Collectors.toList());*/

    String wfid = new BaseBean().getPropValue("qc3189074","wfid");//排班流程id
    String tableName = new BaseBean().getPropValue("qc3189074","tableName");//排班流程主表
    String tableDetailName = new BaseBean().getPropValue("qc3189074","tableDetailName");//排班流程明细表
    public KQLog kqLog = new KQLog();

    /**
     * 保存排班数据
     * @return
     */
    public Map<String,Object> save(Map<String, Object> dataParams, User user){

        //必要的权限判断
        if(!HrmUserVarify.checkUserRight("HrmKQGroup:Add",user)) {
            Map<String, Object> reusltMap = new HashMap<>();
            reusltMap.put("status", "-1");
            reusltMap.put("message", SystemEnv.getHtmlLabelName(2012, user.getLanguage()));
            return reusltMap;
        }

        List<List<Object>> insertList =null;
        Map<String,List<List<Object>>> resourceData = new LinkedHashMap<>();//人员排班
        String groupId = "";
        String kqMonth = "";
        String resourceIds = "";
        try {
            ResourceComInfo resourceComInfo = new ResourceComInfo();


            String data = Util.null2String(dataParams.get("data"));
            JSONObject jsonObj = JSON.parseObject(data);
            KQGroupComInfo kqGroupComInfo = new KQGroupComInfo();
            KQShiftManagementComInfo kqShiftScheduleComInfo = new KQShiftManagementComInfo();
            ResourceComInfo rci = new ResourceComInfo();
             groupId = Util.null2String(jsonObj.get("groupId"));
             kqMonth = Util.null2String(jsonObj.get("kqMonth"));
            JSONArray datas = jsonObj.getJSONArray("datas");

            List<Object> params = null;
            String delIds = "";

            JSONObject resourceDataObj = null;
            JSONArray arrKqDataObj = null;
            JSONObject kqDataObj = null;


            if (datas.size() > 0){
                for(int i=0;i<datas.size();i++){

                    resourceDataObj = (JSONObject)datas.get(i);
                    String resourceid = Util.null2String(resourceDataObj.get("resourceid"));//人员id
                    String departmentID = resourceComInfo.getDepartmentID(resourceid);//部门id
                    String subCompanyID = resourceComInfo.getSubCompanyID(resourceid);//分部id

                    String jobTitle = resourceComInfo.getJobTitle(resourceid);//岗位id

                    //给每个人员创建一个key,保存排班信息
                    if (resourceData.get(resourceid) == null){
                        insertList = new ArrayList<List<Object>>();
                    }else {
                        insertList = resourceData.get(resourceid);
                    }
                    arrKqDataObj = resourceDataObj.getJSONArray("kqdata");
                    for(int j=0;arrKqDataObj!=null&&j<arrKqDataObj.size();j++) {
                        kqDataObj = (JSONObject) arrKqDataObj.get(j);
                        // 如果id为空，则代表原先是空白单元格
                        String id = Util.null2String(kqDataObj.get("id"));
                        String date = Util.null2String(kqDataObj.get("date"));
                        if(!SaveShiftScheduleCmd.isDate(date)) {
                            continue;
                        }
                        // 原先排班的班次id
                        String oldSerialid = Util.null2String(kqDataObj.get("oldValue"));
                        // 新班次id    如果 serialid是-999， oldValue是班次id，那么就是原先是有班次的，后面把班次删除了
                        String serialid = Util.null2String(kqDataObj.get("serialid"));
                        if(serialid.equals("-999"))serialid="";
                        if (serialid.length() > 0){
                            params = new ArrayList<Object>();
                            params.add(resourceid);//排班人员
                            params.add(subCompanyID);//排班人员分部
                            params.add(departmentID);//排班人员部门
                            params.add(jobTitle);//排班人员岗位
                            params.add(date);//排班日期
                            params.add(serialid);//排班班次id
                            params.add(groupId);//排班考勤组
                            insertList.add(params);
                        }
                    }
                    //2024-08-28
                    boolean flag = checkStatus(resourceid, groupId, kqMonth);
                    if (flag){
                        //只有有未审批数据的人才能提交
                        resourceData.put(resourceid,insertList);
                        resourceIds += resourceid+",";
                    }
                }
            }else {
                //没有数据就走全部人员
                    ResourceUtil resourceUtil = new ResourceUtil();
                    resourceData = resourceUtil.getAllResourceIds(kqMonth, groupId);
                    Set<String> keySet =resourceData.keySet(); //获取到所有值
                    for(String key : keySet ){
                        //把排班人员获取下
                        resourceIds += key +",";
                    }
            }
        } catch (Exception e) {
            kqLog.info("saveCustomScheduleError:" + e);
        }

        if (resourceIds.length() > 0){
            resourceIds = resourceIds.substring(0,resourceIds.length()-1);
        }

        new BaseBean().writeLog("resourceData:" + JSON.toJSONString(resourceData));
        if (resourceData.size() <= 0){
            Map<String, Object> reusltMap = new HashMap<>();
            reusltMap.put("status","-1");
            reusltMap.put("message","当前班次数据无变动，请修改保存后再提交");
            return reusltMap;
        }
        Map<String, Object> resultMap = submit(resourceData, kqMonth, groupId, user,resourceIds);
        return resultMap;
    }

    /**
     * 触发排班流程
     * @param resourceData
     * @param kqMonth
     * @param kqGroupId
     * @param user
     * @return
     */

    public Map<String,Object> submit(Map<String,List<List<Object>>> resourceData,String kqMonth,String kqGroupId,User user,String resourceIds){
        CustomRequestUtil customRequestUtil = new CustomRequestUtil();
        Map<String, String> mainParam = new HashMap<>();
        Map<String,Object> reusltMap = new HashMap<>();
        try {
            //处理主表,先获取下操作人员信息
            ResourceComInfo resourceComInfo = new ResourceComInfo();
            String operaterId = JSON.toJSONString(user.getUID());//提交人id
            String operaterSubCompany = resourceComInfo.getSubCompanyID(operaterId);//提交人分部
            String operaterDepartment = resourceComInfo.getDepartmentID(operaterId);//提交人部门
            String operaterJobTitle = resourceComInfo.getJobTitle(operaterId);//提交人岗位
            String type = "0";

            mainParam.put("operaterId",operaterId);
            mainParam.put("operaterSubCompany",operaterSubCompany);
            mainParam.put("operaterDepartment",operaterDepartment);
            mainParam.put("operaterJobTitle",operaterJobTitle);
            mainParam.put("type",type);
            mainParam.put("scheduleResourceIds",resourceIds);//被排班人员id
            mainParam.put("kqMonth",kqMonth);//排班月份
            mainParam.put("kqGroupId",kqGroupId);//排班考勤组


            int rejectRequestId = isHaveWf(kqMonth, kqGroupId,operaterId);
            //先判断当前有没有退回流程，有的话就用退回流程提交
            if (rejectRequestId > 0){
                Map<String, String> otherParam = new HashMap<>();
                otherParam.put("deleteAll","1");
                //主表数据
                JSONArray mainDatas = customRequestUtil.setMainTable(mainParam,otherParam);
                //处理明细表
                JSONArray detailDatas = customRequestUtil.setDetailTable(resourceData,otherParam);
                Boolean isSuccess = customRequestUtil.submitRequest(user, rejectRequestId, mainDatas, detailDatas);
                if (isSuccess){
                    setStatus(resourceIds,kqMonth,"2",rejectRequestId,kqMonth);
                    reusltMap.put("status","1");
                    reusltMap.put("message","提交成功");
                    return reusltMap;
                }
            }else {
                Map<String, String> otherParam = new HashMap<>();
                otherParam.put("deleteAll","0");
                //主表数据
                JSONArray mainDatas = customRequestUtil.setMainTable(mainParam,otherParam);
                //处理明细表
                JSONArray detailDatas = customRequestUtil.setDetailTable(resourceData,otherParam);

                int requestId = customRequestUtil.createRequest(user, wfid, mainDatas, detailDatas);
                if (requestId > 0 ){
                    //成功创建完流程，把标识改为审批中
                    setStatus(resourceIds,kqMonth,"2",requestId,kqGroupId);
                    reusltMap.put("status","1");
                    reusltMap.put("message","提交成功");
                    return reusltMap;
                }
            }
        } catch (Exception e) {
            kqLog.info("submitWorkFlowError:"+e);
            reusltMap.put("status","-1");
            reusltMap.put("message","提交报错");
        }
        reusltMap.put("status","-1");
        reusltMap.put("message","提交报错");
        return reusltMap;
    }

    /**
     * 判断当前考勤组是否启用新功能
     * @param params
     * @param user
     * @return
     */
    public Map<String,Object> isOpen(Map<String, Object> params, User user){
        Map<String, Object> resultMap = new HashMap<>();
        String kqGroupId = Util.null2String(params.get("kqGroup"));
        boolean isHave = false;
        //==zj 换成建模表
        if (isOpenGroup(kqGroupId)){
            isHave = true;
        }
        //如果是系统管理员，还是用标准排班功能
        if (user.getUID() == 1){
            isHave = false;
        }
        resultMap.put("ishave",isHave);
        return resultMap;
    }
    public boolean isOpen(String groupId){
        boolean isHave = false;
        if (isOpenGroup(groupId)){
            isHave = true;
        }
        return isHave;
    }
    /**
     * 判断当前是否可以使用标准排班功能(针对启用新功能的考勤组)
     * @param params
     * @param user
     * @return
     */
    public Map<String,Object> isHave(Map<String, Object> params, User user){
        Map<String, Object> resultMap = new HashMap<>();
        RecordSet rs = new RecordSet();
        String kqGroupId = Util.null2String(params.get("kqGroup"));
        String kqMonth = Util.null2String(params.get("kqMonth"));

        boolean isHave = true;
        //如果是非启动新功能的考勤组，则可以直接使用
        if (!isOpenGroup(kqGroupId) || user.getUID() == 1){
            resultMap.put("ishave",isHave);
            return resultMap;
        }
        //判断指定月份是否有在审批流程
        String monthBeginDate = DateUtil.getFirstDayOfMonth(kqMonth+"-01");
        String monthEndDate = DateUtil.getLastDayOfMonth(kqMonth+"-01");

        String sql = "select id from kq_flow_shiftschedule where groupid = "+kqGroupId+" and kqdate between '"+monthBeginDate+"' and '"+monthEndDate+"' and wfidstatus =2";
        sql += " and (isdelete is null or  isdelete <> '1'  or (isdelete='1' and wfidstatus='2'))";
        rs.executeQuery(sql);
        if (rs.next()){
            isHave = false;
        }
        resultMap.put("ishave",isHave);
        return resultMap;
    }
    /**
     * 判断当前人员数据审批状态
     * @param resoruceId
     * @param fromDate
     * @param kqGroupId
     * @return
     */
    public String flowStatus(String resoruceId,String fromDate,String toDate,String kqGroupId){
        boolean flag = true;
        String status = "";
        String message = "未提交";
        RecordSet rs = new RecordSet();

        //未提交
        String sql = "select wfidstatus from kq_flow_shiftschedule where resourceid="+resoruceId+" and groupid = "+kqGroupId+" and kqdate between '"+fromDate+"' and '"+toDate+"'"+
                " and (isdelete is null or  isdelete <> '1' or (isdelete='1' and wfidstatus='1')) and (wfidstatus='1') ";
        rs.executeQuery(sql);
        if (rs.next()){
            status = Util.null2String(rs.getString("wfidstatus"));
            flag = false;
        }

        //审批中
        if (flag){
             sql = "select wfidstatus from kq_flow_shiftschedule where resourceid="+resoruceId+" and groupid = "+kqGroupId+" and kqdate between '"+fromDate+"' and '"+toDate+"'"+
                    " and (isdelete is null or  isdelete <> '1' or (isdelete='1' and wfidstatus='2')) and (wfidstatus='2') ";
            rs.executeQuery(sql);
            if (rs.next()){
                status = Util.null2String(rs.getString("wfidstatus"));
                flag = false;
            }
        }

        //已审批
        if (flag){
            sql = "select wfidstatus from kq_flow_shiftschedule where resourceid="+resoruceId+" and groupid = "+kqGroupId+" and kqdate between '"+fromDate+"' and '"+toDate+"'"+
                    " and (isdelete is null or  isdelete <> '1' or (isdelete='1' and wfidstatus='3')) and (wfidstatus='3') ";
            rs.executeQuery(sql);
            if (rs.next()){
                status = Util.null2String(rs.getString("wfidstatus"));
                flag = false;
            }
        }
        switch (status){
            case "1":
                message = "未提交";
                break;
            case "2":
                message = "审批中";
                break;
            case "3":
                message = "已审批";
        }
        return message;
    }

    /**
     * 将状态进行修改
     * @param resourceIds
     * @param kqMonth
     */
    public void setStatus(String resourceIds,String kqMonth,String status,int requestId,String groupId){
        RecordSet rs = new RecordSet();
        List<List> paramUpdates = new ArrayList<List>();
        List<Object> paramUpdate = null;

        Map<String,Object> params = new HashMap<>();
        params.put("groupId",groupId);
        params.put("isNoAccount","1");
        User user = new User();

        Map<String, List<String>> validateResult = new KqMembersValidateBiz(params, user).getKqMembersValidateList();
        String[] resourceList = resourceIds.split(",");
        String monthBeginDate = DateUtil.getFirstDayOfMonth(kqMonth+"-01");
        String monthEndDate = DateUtil.getLastDayOfMonth(kqMonth+"-01");
        try {
            //根据当前人员的生效日期范围进行修改
            for (int i = 0; i < resourceList.length; i++) {
                String upDateBegin = "";//变更开始日期
                String upDateEnd = "";//变更结束日期
                String resourceId = resourceList[i];
                List<String> validateList = validateResult.get(resourceId);
                String validateBegin= validateList.get(0);//人员生效开始日期
                String validateEnd = validateList.get(1);//人员生效结束日期
                if (validateBegin.compareTo(monthBeginDate) < 0){
                    upDateBegin = monthBeginDate;
                }else {
                    upDateBegin = validateBegin;
                }
                if (validateEnd.compareTo(monthEndDate) > 0){
                    upDateEnd = monthEndDate;
                }else {
                    upDateEnd = validateEnd;
                }
                //装入参数
                paramUpdate = new ArrayList<Object>();
                if ("2".equals(status)){
                    paramUpdate.add(requestId);//流程id
                }
                paramUpdate.add(status);
                paramUpdate.add(resourceId);//人员id
                paramUpdate.add(upDateBegin);//变更开始日期
                paramUpdate.add(upDateEnd);//变更结束日期
                if ("1".equals(status)){
                    paramUpdate.add(requestId);//流程id
                }
                paramUpdates.add(paramUpdate);
            }
            String updateSql = "";
            //==zj 2025-06-06 这里只改非删除数据的班次
            if ("2".equals(status)){
                updateSql = "update kq_flow_shiftschedule set wfid=?, wfidstatus = ? "+
                        "where (isdelete is null or isdelete <> '1') and resourceid=? and kqdate between ? and ? and wfidstatus = 1 ";
            }else if ("1".equals(status)){
                updateSql = "update kq_flow_shiftschedule set wfidstatus = ? "+
                        "where (isdelete is null or isdelete <> '1') and resourceid=? and kqdate between ? and ? and wfid=? and wfidstatus = 2  ";
            }
            rs.executeBatchSql(updateSql,paramUpdates);
        } catch (Exception e) {
            new BaseBean().writeLog("setStatusError:" + e);
        }
    }

    /**
     * 当前月份是否有退回的排班审批流程
     */
    public int isHaveWf(String kqMonth,String kqGruopId,String resourceId){
        int requestId = 0;
        RecordSet rs = new RecordSet();
        String sqlBase = "select a.cjr,a.requestid,a.kqz,a.pbyf from "+tableName + " a left join workflow_requestbase b on a.requestid = b.requestid ";
       String sqlWhere = "where    currentnodetype = 0 and a.kqz="+kqGruopId+" and a.pbyf='"+kqMonth+"' and a.cjr='"+resourceId+"'";

       rs.executeQuery(sqlBase+sqlWhere);
       if (rs.next()){
           requestId = rs.getInt("requestid");
       }
        new BaseBean().writeLog("是否有退回流程："+sqlBase+sqlWhere);
        new BaseBean().writeLog("退回流程id："+requestId);
       return requestId;
    }
    /**
     * 这里检测下当前人员月份的状态,只有未提交状态的才能提交
     * @param gruopId
     * @param kqMonth
     * @return
     */
    public boolean checkStatus(String resourceId,String gruopId,String kqMonth){
        boolean flag = false;
        String monthBeginDate = DateUtil.getFirstDayOfMonth(kqMonth+"-01");
        String monthEndDate = DateUtil.getLastDayOfMonth(kqMonth+"-01");
        RecordSet rs = new RecordSet();
        String sql = "select resourceid,kqdate,groupid from kq_flow_shiftschedule where wfidstatus=1 and groupid="+gruopId+" and kqdate between '"+monthBeginDate+"' and '"+monthEndDate+"' and resourceId="+resourceId;
        rs.executeQuery(sql);
        if (rs.next()){
            flag = true;
        }
        return flag;
    }

    /**
     * 查询建模表，判断当前考勤组是否使用新功能
     * @param groupid
     * @return
     */
    public boolean isOpenGroup(String groupid){
        boolean isOpen = false;
        RecordSet rs = new RecordSet();
        String sql = "select * from uf_pbspkqzb";
        String where = " where EXISTS(" +
                        "SELECT 1 " +
                        "from STRING_SPLIT(CAST(kqz AS NVARCHAR(MAX)), ',') " +
                        "WHERE value = "+groupid+")";
        rs.executeQuery(sql+where);
        if (rs.next()){
            isOpen = true;
        }
        return isOpen;
    }

    /**
     * 判断当前人员所在考勤组的生效日期范围
     * @param resourceIds
     * @param groupId
     * @return
     */
    public Map<String,String> getValidateMap(String resourceIds,String groupId){
        RecordSet rs = new RecordSet();
        Map<String, String> validateMap = new HashMap<>();
        String validatefrom = "";
        String validateto = "";
        String resourceid = "";
        //人员
        String sql = " SELECT distinct a.id AS resourceid, b.groupid,b.validatefrom as validatefrom, b.validateto as validateto, a.status FROM HrmResource a, kq_groupmember b, kq_group c " +
                " WHERE a.id=b.typevalue and b.type =1 and b.groupid=c.id and (c.isdelete is null or c.isdelete <> '1') and (b.isdelete is null or b.isdelete <> '1')" +
                " and a.id in ("+resourceIds+") and b.groupid="+groupId;
        rs.executeQuery(sql);
        while (rs.next()) {
             resourceid = Util.null2String(rs.getString("resourceid"));
             validatefrom = Util.null2String(rs.getString("validatefrom"));
             validateto = Util.null2String(rs.getString("validateto"));
            validateMap.put(resourceid+"|validatefrom",validatefrom);
            validateMap.put(resourceid+"|validateto",validateto);
        }
        return validateMap;
    }
}
