package com.engine.attendance.attendanceanalysis.web;

import com.engine.attendance.attendanceanalysis.service.UtilService;
import com.engine.attendance.attendanceanalysis.service.impl.UtilServiceImpl;
import com.engine.attendance.attendanceanalysis.wrapper.AttendanceAnalysisWrapper;
import com.engine.attendance.attendanceplan.service.AttendancePlanService;
import com.engine.attendance.attendanceplan.service.impl.AttendancePlanServiceImpl;
import com.engine.attendance.workflow.service.AllowanceService;
import com.engine.attendance.workflow.service.impl.AllowanceServiceImpl;
import com.engine.common.util.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class AttendanceanalysisAction {
    private AttendancePlanService basicsetService = ServiceUtil.getService(AttendancePlanServiceImpl.class);
    private UtilService utilService = ServiceUtil.getService(UtilServiceImpl.class);
    private AttendanceAnalysisWrapper attendanceAnalysisService = ServiceUtil.getService(AttendanceAnalysisWrapper.class);
    private AllowanceService allowanceService = ServiceUtil.getService(AllowanceServiceImpl.class);

    /**
     * 排班分析
     * @return
     */
    @POST
    @Path("/attendanceAnalysisByHrmAndDate")
    @Produces({"text/plain"})
    public String getSchedulingData(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            Map<String,Object> paramMap = ParamUtil.request2Map(request);
//            Map<String,Object> paramMap = Maps.newHashMap();
//            paramMap.put("startDate","2024-05-02");
//            paramMap.put("endDate","2024-05-02");
//            paramMap.put("userIds","27");


            String startDate = Util.null2String(paramMap.get("startDate"));
            String startBeforeDate = DateUtil.beforeDay(startDate,2);
            String endDate = Util.null2String(paramMap.get("endDate"));
            String endAfterDate = DateUtil.AfterDay(endDate,2);
            String userIds = Util.null2String(paramMap.get("userIds"));
            int betweenDays = DateUtil.getBetWeenDays(startDate,endDate);
            if ("".equals(userIds)){
                String queryUserSql = "select id from hrmresource where  (status = 0 or status = 1 or status = 2 or status = 3)  and status != 10";
                List<Map<String,Object>> userList = DbTools.getSqlToList(queryUserSql);
                String sql = "select id,userid,signdate,signtime from hrmschedulesign where isincom=1 and signdate >= ? and signdate <= ? order by signdate,signtime";
                List<Map<String,Object>> dataList = DbTools.getSqlToList(sql,startBeforeDate,endAfterDate);
                //补打卡记录
                sql = "select id,bdkry userid,dkrq signdate,dksj signtime from uf_jcl_kq_bdkjl where dkrq >= ? and dkrq <= ? order by dkrq,dksj";
                List<Map<String,Object>> makeUpList = DbTools.getSqlToList(sql,startBeforeDate,endAfterDate);
                if (makeUpList.size() > 0){
                    dataList.addAll(makeUpList);
                }
                dataList = dataList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("signdate")+" "+e.get("signtime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());



                Map<String, List<Map<String,Object>>> collect = dataList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("userid"))));

                for (Map<String,Object> userMap :userList){
                    String userId = userMap.get("id").toString();
                    //出勤结果，进出时间
                    Map<String,Map<String,Object>> clockInTimeMap = Maps.newHashMap();
                    /**获得人员考勤项目*/
                    Map<String,Object> param = Maps.newHashMap();
                    param.put("startDate",startBeforeDate);
                    param.put("endDate",endAfterDate);
                    param.put("resourceId",userId);
                    Map<String,Object> dataMap = basicsetService.getAttendanceItemsByPerson(param);
                    List<Map<String,Object>> attendanceItems = (List<Map<String,Object>>)dataMap.get("data");

                    /**
                     *获得人员综合工时
                     */
                    Map<String,Object> workHourdataMap = basicsetService.getWorkHoursItemByPerson(param);
                    List<Map<String,Object>> workHourItems = (List<Map<String,Object>>)workHourdataMap.get("data");

                    /** 获取人员班次*/
                    Map<String,Object> classesParamMap = Maps.newHashMap();
                    classesParamMap.put("tableName","uf_pbjg");
                    classesParamMap.put("startDate",startBeforeDate);
                    classesParamMap.put("endDate",endAfterDate);
                    classesParamMap.put("pblx","0");
                    classesParamMap.put("pbdx",userId);
                    classesParamMap.put("current","1");
                    classesParamMap.put("pageSize",10);
                    classesParamMap.put("recurrence",1);
                    classesParamMap.put("clockInTimeMap",clockInTimeMap);
                    classesParamMap.put("clockInData",dataList);
                    classesParamMap.put("attendanceItems",attendanceItems);
                    Map<String,Object> schedulMap = utilService.getSchedulingInFormation(classesParamMap);

                    for (int i=0; i<=betweenDays;i++){
                        String date = DateUtil.AfterDay(startDate,i);
                        attendanceAnalysisService.attendanceAnalysisForApi(userId,date,collect.get(userId),attendanceItems,schedulMap,workHourItems,clockInTimeMap);
                    }
                    allowanceService.addAllowanceRecords(paramMap);
                }
            }else {
                String sql = "select id,userid,signdate,signtime from hrmschedulesign where isincom=1 and userid in ("+userIds+") and  signdate >= ? and signdate <= ? order by signdate,signtime";
                List<Map<String,Object>> dataList = DbTools.getSqlToList(sql,startBeforeDate,endAfterDate);
                //补打卡记录
                sql = "select id,bdkry userid,dkrq signdate,dksj signtime from uf_jcl_kq_bdkjl where bdkry in ("+userIds+") and dkrq >= ? and dkrq <= ? order by dkrq,dksj";
                List<Map<String,Object>> makeUpList = DbTools.getSqlToList(sql,startBeforeDate,endAfterDate);
                if (makeUpList.size() > 0){
                    dataList.addAll(makeUpList);
                }
                dataList = dataList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("signdate")+" "+e.get("signtime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());


                Map<String, List<Map<String,Object>>> collect = dataList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("userid"))));

                for (String userId : userIds.split(",")){
                    /**获得人员考勤项目*/
                    Map<String,Object> param = Maps.newHashMap();
                    //出勤结果，进出时间
                    Map<String,Map<String,Object>> clockInTimeMap = Maps.newHashMap();
                    param.put("startDate",startBeforeDate);
                    param.put("endDate",endAfterDate);
                    param.put("resourceId",userId);
                    Map<String,Object> dataMap = basicsetService.getAttendanceItemsByPerson(param);
                    List<Map<String,Object>> attendanceItems = (List<Map<String,Object>>)dataMap.get("data");

                    /**
                     *获得人员综合工时
                     */
                    Map<String,Object> workHourdataMap = basicsetService.getWorkHoursItemByPerson(param);
                    List<Map<String,Object>> workHourItems = (List<Map<String,Object>>)workHourdataMap.get("data");


                    /** 获取人员班次*/
                    Map<String,Object> classesParamMap = Maps.newHashMap();
                    classesParamMap.put("tableName","uf_pbjg");
                    classesParamMap.put("startDate",startBeforeDate);
                    classesParamMap.put("endDate",endAfterDate);
                    classesParamMap.put("pblx","0");
                    classesParamMap.put("pbdx",userId);
                    classesParamMap.put("current","1");
                    classesParamMap.put("pageSize",10);
                    classesParamMap.put("recurrence",1);
                    classesParamMap.put("clockInTimeMap",clockInTimeMap);
                    classesParamMap.put("clockInData",dataList);
                    classesParamMap.put("attendanceItems",attendanceItems);
                    Map<String,Object> schedulMap = utilService.getSchedulingInFormation(classesParamMap);

                    for (int i=0; i<=betweenDays;i++){
                        String date = DateUtil.AfterDay(startDate,i);
                        attendanceAnalysisService.attendanceAnalysisForApi(userId,date,collect.get(userId),attendanceItems,schedulMap,workHourItems,clockInTimeMap);
                    }
                }
                paramMap.put("empIds",paramMap.get("userIds"));
                allowanceService.addAllowanceRecords(paramMap);
            }
            return null;
        }catch (Exception e){
            log.error("execute fail,catch error: [{}]",e);
            return ApiReturnTools.error("500","attendanceAnalysisByHrmAndDate error");
        }
    }

    /**
     * 获得分析数据
     * @return
     */
    @POST
    @Path("/getAnalysisDate")
    @Produces({"text/plain"})
    public String getAnalysisDate(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            Map<String,Object> paramMap = ParamUtil.request2Map(request);
            String startDate = Util.null2String(paramMap.get("startDate"));

            String endDate = Util.null2String(paramMap.get("endDate"));

            String userIds = Util.null2String(paramMap.get("userIds"));
            String sql = "select id,userid,signdate,signtime from hrmschedulesign where isincom=1 and userid in ("+userIds+") and  signdate >= ? and signdate <= ? order by signdate,signtime";
            List<Map<String,Object>> dataList = DbTools.getSqlToList(sql,DateUtil.beforeDay(startDate,1),DateUtil.AfterDay(endDate,1));
            Map<String, List<Map<String,Object>>> collect = dataList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("userid"))));

            //考勤项目
            sql = "select id,mc from uf_jcl_kq_kqxm";
            List<Map<String,Object>> items = DbTools.getSqlToList(sql);
            Map<String,String> itemMap = items.stream().collect(Collectors.toMap(e->Util.null2String(e.get("id")),e->Util.null2String(e.get("mc"))));


            //请假记录
            sql = "select a.qjry,a.jqlx,a.cxjqj,b.ksrq,b.kssj,b.jsrq,b.jssj,b.qjsc,b.qtj,b.btj from uf_jcl_kq_qjjl a left join uf_jcl_kq_qjjl_dt1 b on a.id = b.mainid where a.qjry in ("+userIds+") and b.ksrq>=? and b.ksrq<=? and (b.cxqj=0 or b.cxqj is null) order by b.ksrq,b.kssj";
            List<Map<String,Object>> askforLeaveList = DbTools.getSqlToList(sql,startDate,endDate);
            for (Map<String,Object> map :askforLeaveList){
                map.put("jqlx_name",itemMap.get(map.get("jqlx")));
            }
            Map<String, List<Map<String,Object>>> askforLeavecollect = askforLeaveList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("qjry"))));

            //出差记录
            sql = "select b.ccr,a.cclx,a.ccsd,b.ksrq,b.jsrq,b.kssj,b.jssj,b.ccsc,b.qtcc,b.btcc,b.cxcc from uf_jcl_kq_ccjl a left join uf_jcl_kq_ccjl_dt1 b on a.id = b.mainid where b.ccr in ("+userIds+") and b.ksrq>=? and b.ksrq<=? and (b.cxcc=0 or b.cxcc is null) order by b.ksrq,b.kssj";
            List<Map<String,Object>> evectionList = DbTools.getSqlToList(sql,startDate,endDate);
            for (Map<String,Object> map :evectionList){
                map.put("cclx_name",itemMap.get(map.get("cclx")));
            }
            Map<String, List<Map<String,Object>>> evectioncollect = evectionList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("ccr"))));

            //加班计划
            sql = "select b.jbry,b.ksrq,b.kssj,a.jblx,b.jsrq,b.jssj,b.jbsc from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on a.id=b.mainid where b.jbry in ("+userIds+") and b.ksrq>=? and b.ksrq<=? and (b.jbcx=0 or b.jbcx is null) order by b.ksrq,b.kssj";
            List<Map<String,Object>> overPlanDataList = DbTools.getSqlToList(sql,startDate,endDate);
            for (Map<String,Object> map :overPlanDataList){
                map.put("jblx_name",itemMap.get(map.get("jblx")));
            }
            Map<String, List<Map<String,Object>>> overPlancollect = overPlanDataList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("jbry"))));

            //加班结果
            sql = "select szjg,jbry,sjksrq,jbjgly,sjjsrq,sjkssj,sjjssj,sjjbsc,jblx,zt from uf_jcl_kq_jbjg where jbry in ("+userIds+") and sjksrq>=? and sjjsrq<=? order by sjksrq,sjkssj";
            List<Map<String,Object>> overPlanResultList = DbTools.getSqlToList(sql,startDate,endDate);
            for (Map<String,Object> map :overPlanResultList){
                map.put("jblx_name",itemMap.get(map.get("jblx")));
            }
            Map<String, List<Map<String,Object>>> overResultcollect = overPlanResultList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("jbry"))));




            List<Map<String,Object>> resultList = Lists.newArrayList();
            for (String userId : userIds.split(",")){
                Map<String,Object> map = Maps.newHashMap();
                Map<String,List<Map<String,Object>>> map1 = Maps.newHashMap();
                map1.put("signDate",collect.get(userId));
                map1.put("askforLeave",askforLeavecollect.get(userId));
                map1.put("evection",evectioncollect.get(userId));
                map1.put("overPlan",overPlancollect.get(userId));
                map1.put("overResult",overResultcollect.get(userId));
                map.put("userId",userId);
                map.put("data",map1);
                resultList.add(map);
            }


            return ApiReturnTools.success(resultList);
        }catch (Exception e){
            log.error("execute fail,catch error: [{}]",e);
            return ApiReturnTools.error("500","saveApplicableOrganization error");
        }
    }

    /**
     * 获得已经设置为默认日历的日历名称信息
     */
    @POST
    @Path("/getDefaultCalendar")
    @Produces({"text/plain"})
    public String getDefaultCalendar(@Context HttpServletRequest request, @Context HttpServletResponse response){
        try {
            Map<String,Object> paramMap = ParamUtil.request2Map(request);
            String sql = "select id, szjg, rlmc, rlsm from uf_jcl_kq_rlmc where mrrl = '1' and szjg=?";
            List<Map<String,Object>> calendarList = DbTools.getSqlToList(sql,paramMap.get("szjg"));
            return ApiReturnTools.success(calendarList);
        }catch (Exception e){
            log.error("execute fail,catch error: [{}]",e);
            return ApiReturnTools.error("500","saveApplicableOrganization error");
        }
    }

    /**
     * 将所有的企业日历取消默认值标记
     */
    @POST
    @Path("/dumpDefaultCalendar")
    @Produces({"text/plain"})
    public String dumpDefaultCalendar(@Context HttpServletRequest request, @Context HttpServletResponse response){
        try {
            Map<String,Object> paramMap = ParamUtil.request2Map(request);
            String sql = "update uf_jcl_kq_rlmc set mrrl = '0' where szjg=?";
            List<Map<String,Object>> resultList = Lists.newArrayList();
            Map<String,Object> map = Maps.newHashMap();
            if(DbTools.update(sql,paramMap.get("szjg")))
                map.put("update","1");
            else
                map.put("update","0");
            resultList.add(map);
            return ApiReturnTools.success(resultList);
        }catch (Exception e){
            log.error("execute fail,catch error: [{}]",e);
            return ApiReturnTools.error("500","saveApplicableOrganization error");
        }
    }

    /**
     * 获得当前日历被引用的次数
     */
    @POST
    @Path("/getCalendarRef")
    @Produces({"text/plain"})
    public String getCalendarRef(@Context HttpServletRequest request, @Context HttpServletResponse response){
        try {
            Map<String,Object> paramMap = ParamUtil.request2Map(request);
            String calendarId = Util.null2String(paramMap.get("id"));
            String sql = "select count(id) refcount from uf_jcl_kq_glpb where qyrl = "+calendarId;
            List<Map<String,Object>> calendarList = DbTools.getSqlToList(sql);
            return ApiReturnTools.success(calendarList);
        }catch (Exception e){
            log.error("execute fail,catch error: [{}]",e);
            return ApiReturnTools.error("500","saveApplicableOrganization error");
        }
    }
}
