package yangtz.cs.liu.dingding.service.impl.dingClock;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dingtalk.api.response.OapiAttendanceGetleavestatusResponse;
import com.dingtalk.api.response.OapiAttendanceListRecordResponse;
import com.ruoyi.common.core.domain.entity.SchoolTeacher;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yangtz.cs.liu.campus.domain.schoolAtt.SchoolAtt;
import yangtz.cs.liu.campus.domain.teacher.SchoolTeacherLeave;
import yangtz.cs.liu.campus.mapper.schoolAtt.SchoolAttMapper;
import yangtz.cs.liu.campus.mapper.teacher.SchoolTeacherMapper;
import yangtz.cs.liu.campus.service.schoolAtt.ISchoolAttService;
import yangtz.cs.liu.campus.service.teacher.ISchoolTeacherLeaveService;
import yangtz.cs.liu.dingding.service.dingClock.IDingClockService;
import yangtz.cs.liu.dingding.utils.DingClockUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class DingClockServiceImpl implements IDingClockService {

    @Autowired
    private DingClockUtils dingClockUtils;
    @Autowired
    private SchoolTeacherMapper teacherMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private ISchoolAttService attService;
    @Autowired
    private SysDeptMapper deptMapper;
    @Autowired
    private ISchoolTeacherLeaveService teacherLeaveService;

    /**
     * 获取全部用户一周内打卡记录
     */
    @Override
    @Transactional
    public String getListRecord(){
        //查询所有教师(管理员账号除外)
        List<SchoolTeacher> schoolTeachers = teacherMapper.selectClockTeacher();

        //查询所有教师用户
        List<SysUser> userList = userMapper.selectUserList(new SysUser());

        //查询所有部门
        List<SysDept> sysDepts = deptMapper.selectDeptList(new SysDept());

        //存放钉钉用户id集合
        List<String> ddUserIds = new ArrayList<>();
        //遍历拿出所有钉钉用户id
        if (schoolTeachers.size() > 0){
            for (SchoolTeacher schoolTeacher : schoolTeachers) {
                if (StringUtils.isNotEmpty(schoolTeacher.getDdUserId())){
                    ddUserIds.add(schoolTeacher.getDdUserId());
                }
            }
        }

//        //获取本周周一日期
//        Calendar c = Calendar.getInstance();
//        //设置周一为一周的第一天
//        c.setFirstDayOfWeek(Calendar.MONDAY);
//        c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
//        Date time = c.getTime();
        //获取本月第一天
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time = cal.getTime();

        //查询用户打卡详情需要的时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //查询考勤打卡记录的起始工作日
//        String checkDateFrom = sdf.format(time) + " 00:00:00";
        String checkDateFrom = "2023-12-22" + " 00:00:00";
        //查询考勤打卡记录的结束工作日
//        String checkDateTo = sdf.format(new Date()) + " 23:59:59";
        String checkDateTo = "2023-12-26" + " 23:59:59";

        //用户打卡时间转换
        SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm:ss");

        //存放用户打卡记录集合
        List<SchoolAtt> schoolAttList = new ArrayList<>();

        //用户查询用户打卡详情，最多存放五十个钉钉用户id
        List<String> userIdListResult = new ArrayList<>();
        if (ddUserIds.size() > 50){
            for (int i = 0; 50 * i < ddUserIds.size(); i++) {
                userIdListResult = ddUserIds.subList(50 * i, Math.min(ddUserIds.size(), 50 * (i + 1)));
                List<OapiAttendanceListRecordResponse.Recordresult> recordresults = dingClockUtils.listRecord(userIdListResult, checkDateFrom, checkDateTo, false);
                if (StringUtils.isNotNull(recordresults) && recordresults.size() > 0){
                    for (OapiAttendanceListRecordResponse.Recordresult recordresult : recordresults) {
                        SchoolAtt schoolAtt = new SchoolAtt();
                        for (SchoolTeacher schoolTeacher : schoolTeachers) {
                            if (recordresult.getUserId().equals(schoolTeacher.getDdUserId())){
                                //打卡记录
                                schoolAtt.setDeviceNum(schoolTeacher.getDeviceNum());
                                schoolAtt.setTeacherCode(schoolTeacher.getTeacherCode());
                                schoolAtt.setUserId(schoolTeacher.getId());
                                schoolAtt.setUserName(schoolTeacher.getTeacherName());
                                for (SysUser sysUser : userList) {
                                    if (schoolTeacher.getId().equals(sysUser.getUserId())){
                                        schoolAtt.setOrgid(sysUser.getDeptId());
                                        for (SysDept sysDept : sysDepts) {
                                            if (sysDept.getDeptId().equals(sysUser.getDeptId())){
                                                schoolAtt.setOrgname(sysDept.getDeptName());
                                            }
                                        }
                                    }
                                }
                                //打卡日期
                                schoolAtt.setClockDate(recordresult.getUserCheckTime());
                                //打卡时间
                                schoolAtt.setClockTime(sdf1.format(recordresult.getUserCheckTime()));
                                //打卡状态
                                if (StringUtils.isNotEmpty(recordresult.getTimeResult())){
                                    String workStatus = "";
                                    switch (recordresult.getTimeResult()){
                                        case "Normal":
                                            workStatus = "正常";
                                            break;
                                        case "Early":
                                            workStatus = "早退";
                                            break;
                                        case "Late":
                                            workStatus = "迟到";
                                            break;
                                        case "SeriousLate":
                                            workStatus = "严重迟到";
                                            break;
                                        case "Absenteeism":
                                            workStatus = "旷工迟到";
                                            break;
                                        case "NotSigned":
                                            workStatus = "未打卡";
                                            break;
                                    }
                                    schoolAtt.setWorkStatus(workStatus);
                                }
                                //备注
                                schoolAtt.setRemark(recordresult.getOutsideRemark());
//                                attMapper.insertSchoolAtt(schoolAtt);
                                schoolAttList.add(schoolAtt);
                            }
                        }
                    }
                }
            }
        }else {
            userIdListResult = ddUserIds;
            List<OapiAttendanceListRecordResponse.Recordresult> recordresults = dingClockUtils.listRecord(userIdListResult, checkDateFrom, checkDateTo, false);
            if (recordresults.size() > 0){
                for (OapiAttendanceListRecordResponse.Recordresult recordresult : recordresults) {
                    SchoolAtt schoolAtt = new SchoolAtt();
                    for (SchoolTeacher schoolTeacher : schoolTeachers) {
                        if (recordresult.getUserId().equals(schoolTeacher.getDdUserId())){
                            schoolAtt.setDeviceNum(schoolTeacher.getDeviceNum());
                            schoolAtt.setTeacherCode(schoolTeacher.getTeacherCode());
                            schoolAtt.setUserId(schoolTeacher.getId());
                            schoolAtt.setUserName(schoolTeacher.getTeacherName());
                            for (SysUser sysUser : userList) {
                                if (schoolTeacher.getId().equals(sysUser.getUserId())){
                                    schoolAtt.setOrgid(sysUser.getDeptId());
                                    for (SysDept sysDept : sysDepts) {
                                        if (sysDept.getDeptId().equals(sysUser.getDeptId())){
                                            schoolAtt.setOrgname(sysDept.getDeptName());
                                        }
                                    }
                                }
                            }
                            //打卡日期
                            schoolAtt.setClockDate(recordresult.getUserCheckTime());
                            //打卡时间
                            schoolAtt.setClockTime(sdf1.format(recordresult.getUserCheckTime()));
                            //打卡状态
                            if (StringUtils.isNotEmpty(recordresult.getTimeResult())){
                                String workStatus = "";
                                switch (recordresult.getTimeResult()){
                                    case "Normal":
                                        workStatus = "正常";
                                        break;
                                    case "Early":
                                        workStatus = "早退";
                                        break;
                                    case "Late":
                                        workStatus = "迟到";
                                        break;
                                    case "SeriousLate":
                                        workStatus = "严重迟到";
                                        break;
                                    case "Absenteeism":
                                        workStatus = "旷工迟到";
                                        break;
                                    case "NotSigned":
                                        workStatus = "未打卡";
                                        break;
                                }
                                schoolAtt.setWorkStatus(workStatus);
                            }
                            //备注
                            schoolAtt.setRemark(recordresult.getOutsideRemark());
//                            attMapper.insertSchoolAtt(schoolAtt);
                            schoolAttList.add(schoolAtt);
                        }
                    }
                }
            }
        }
        //批量新增打卡记录
        boolean b = attService.saveBatch(schoolAttList);
        if (b){
            return "操作成功";
        }
        return "操作失败";
    }

    /**
     * 获取全部用户一周内请假信息
     */
    @Override
    @Transactional
    public String getTeacherLeave(){
        //查询所有教师(管理员账号除外)
        List<SchoolTeacher> schoolTeachers = teacherMapper.selectClockTeacher();

        //钉钉用户id
        List<String> ddUserIds = new ArrayList<>();

        //遍历拿出所有钉钉用户id
        if (schoolTeachers.size() > 0){
            for (SchoolTeacher schoolTeacher : schoolTeachers) {
                if (StringUtils.isNotEmpty(schoolTeacher.getDdUserId())){
                    ddUserIds.add(schoolTeacher.getDdUserId());
                }
            }
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //获取本周周一到周日的日期日期
        Calendar c = Calendar.getInstance();
        //设置周一为一周的第一天
        c.setFirstDayOfWeek(Calendar.MONDAY);
        //周一的日期
        c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        Long monday = null;
        try {
            monday = sdf.parse(sdf.format(c.getTime())).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //当前的日期
        Long sunday = null;
        try {
            sunday = sdf.parse(sdf.format(new Date())).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //偏移量，相当于页码
        Long offset = 0L;

        //存放所有钉钉用户请假状态
        List<OapiAttendanceGetleavestatusResponse.LeaveStatusVO> leaveStatus = new ArrayList<>();

        //存放全部教师请假申请
        List<SchoolTeacherLeave> schoolTeacherLeaveList = new ArrayList<>();


        //用户查询用户打卡详情，最多存放100个钉钉用户id
        List<String> userIdListResult = new ArrayList<>();
        if (ddUserIds.size() > 100){
            for (int i = 0; 100 * i < ddUserIds.size(); i++) {
                userIdListResult = ddUserIds.subList(100 * i, Math.min(ddUserIds.size(), 100 * (i + 1)));
                String userIds = "";
                for (int i1 = 0; i1 < userIdListResult.size(); i1++) {
                    if (i1 == userIdListResult.size() - 1){
                        userIds += userIdListResult.get(i1);
                    }else {
                        userIds += userIdListResult.get(i1) + ",";
                    }
                }
                //请求查询用户请假状态
                OapiAttendanceGetleavestatusResponse.LeaveStatusListVO getleavestatus = dingClockUtils.getleavestatus(userIds, monday, sunday, offset, 20L);
                if (StringUtils.isNotNull(getleavestatus.getLeaveStatus()) && getleavestatus.getLeaveStatus().size() > 0){
                    leaveStatus.addAll(getleavestatus.getLeaveStatus());
                }
                if (StringUtils.isNotNull(getleavestatus.getHasMore())){
                    //判断是否还有数据
                    while (getleavestatus.getHasMore()) {
                        OapiAttendanceGetleavestatusResponse.LeaveStatusListVO getleavestatus1 = dingClockUtils.getleavestatus(userIds, monday, sunday, offset, 20L);
                        if (StringUtils.isNotNull(getleavestatus1.getLeaveStatus()) && getleavestatus1.getLeaveStatus().size() > 0){
                            leaveStatus.addAll(getleavestatus1.getLeaveStatus());
                        }
                        if (StringUtils.isNull(getleavestatus1.getHasMore()) || getleavestatus1.getHasMore().equals(false)){
                            break;
                        }
                        offset ++;
                    }
                }
            }
        }else {
            userIdListResult = ddUserIds;
            String userIds = "";
            for (int i1 = 0; i1 < userIdListResult.size(); i1++) {
                if (i1 == userIdListResult.size() - 1){
                    userIds += userIdListResult.get(i1);
                }else {
                    userIds += userIdListResult.get(i1) + ",";
                }
            }
            //请求查询用户请假状态
            OapiAttendanceGetleavestatusResponse.LeaveStatusListVO getleavestatus = dingClockUtils.getleavestatus(userIds, monday, sunday, offset, 20L);
            if (StringUtils.isNotNull(getleavestatus.getLeaveStatus()) && getleavestatus.getLeaveStatus().size() > 0){
                leaveStatus.addAll(getleavestatus.getLeaveStatus());
            }
            if (StringUtils.isNotNull(getleavestatus.getHasMore())){
                //判断是否还有数据
                while (getleavestatus.getHasMore()) {
                    OapiAttendanceGetleavestatusResponse.LeaveStatusListVO getleavestatus1 = dingClockUtils.getleavestatus(userIds, monday, sunday, offset, 20L);
                    if (StringUtils.isNotNull(getleavestatus1.getLeaveStatus()) && getleavestatus1.getLeaveStatus().size() > 0){
                        leaveStatus.addAll(getleavestatus1.getLeaveStatus());
                    }
                    if (StringUtils.isNull(getleavestatus1.getHasMore()) || getleavestatus1.getHasMore().equals(false)){
                        break;
                    }
                    offset ++;
                }
            }
        }

        //循环钉钉用户请假状态，给教师请假实体对象赋值
        if (leaveStatus.size() > 0){
            for (OapiAttendanceGetleavestatusResponse.LeaveStatusVO status : leaveStatus) {
                for (SchoolTeacher schoolTeacher : schoolTeachers) {
                    if (status.getUserid().equals(schoolTeacher.getDdUserId())){
                        SchoolTeacherLeave teacherLeave = new SchoolTeacherLeave();
                        teacherLeave.setTitle(schoolTeacher.getTeacherName() + "的请假申请");
                        teacherLeave.setTeacherId(schoolTeacher.getId());
                        teacherLeave.setTeacherName(schoolTeacher.getTeacherName());
                        teacherLeave.setStartTime(new Date(status.getStartTime()));
                        teacherLeave.setEndTime(new Date(status.getEndTime()));
                        //单位为小时，换算成天数(从钉钉获取的时长自动乘了100，存系统数据库前需手动除以100，为实际请假时长)
                        if (status.getDurationUnit().equals("percent_hour")){
                            teacherLeave.setTotalTime(Double.parseDouble(String.format("%.3f",Double.parseDouble(status.getDurationPercent() + "") / 24 / 100)));
                        }else {
                            teacherLeave.setTotalTime(Double.parseDouble(String.format("%.3f",Double.parseDouble(status.getDurationPercent() + "") / 100)));
                        }
                        teacherLeave.setState("0");
                        teacherLeave.setApplyUserId(schoolTeacher.getId());
                        teacherLeave.setApplyUser(schoolTeacher.getTeacherName());
                        schoolTeacherLeaveList.add(teacherLeave);
                    }
                }
            }
        }

        //根据教师id，开始时间、结束时间去重
        List<SchoolTeacherLeave> teacherLeaveList = schoolTeacherLeaveList
                .stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator
                        .comparing(o -> o.getTeacherId() + ";" + o.getStartTime() + ";" + o.getEndTime()))),ArrayList::new));

        //批量新增教师请假
        boolean b = teacherLeaveService.saveBatch(teacherLeaveList);
        if (b){
            return "操作成功";
        }
        return "操作失败";
    }
}
