package com.xjrsoft.module.job;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.XjrSoftApplication;
import com.xjrsoft.common.enums.WeChatType;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.common.utils.WeChatUtil;
import com.xjrsoft.config.CommonPropertiesConfig;
import com.xjrsoft.module.attendance.entity.AttendanceMessageSet;
import com.xjrsoft.module.attendance.entity.AttendanceMessageUserRelation;
import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
import com.xjrsoft.module.attendance.service.IAttendanceMessageSetService;
import com.xjrsoft.module.attendance.service.IAttendanceRuleCategoryService;
import com.xjrsoft.module.concat.service.IXjrUserService;
import com.xjrsoft.module.holiday.entity.HolidayDate;
import com.xjrsoft.module.holiday.service.IHolidayDateService;
import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
import com.xjrsoft.module.organization.entity.UserRoleRelation;
import com.xjrsoft.module.organization.service.IWeChatService;
import com.xjrsoft.module.outint.entity.StudentOutInRecord;
import com.xjrsoft.module.outint.entity.TeacherOutInRecord;
import com.xjrsoft.module.outint.service.IStudentOutInRecordService;
import com.xjrsoft.module.outint.service.ITeacherOutInRecordService;
import com.xjrsoft.module.student.entity.BaseStudent;
import com.xjrsoft.module.system.entity.WechatMessageLog;
import com.xjrsoft.module.system.service.IWechatMessageLogService;
import com.xjrsoft.module.teacher.entity.BaseTeacher;
import com.xjrsoft.module.teacher.entity.XjrUser;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author dzx
 * @date 2024/5/23
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = XjrSoftApplication.class)
class AttendanceMessageTaskTest {
    @Autowired
    private IAttendanceMessageSetService messageSetService;

    @Autowired
    private IAttendanceRuleCategoryService ruleCategoryService;

    @Autowired
    private IHolidayDateService holidayDateService;

    @Autowired
    private IXjrUserService userService;

    @Autowired
    private IStudentOutInRecordService studentOutInRecordService;

    @Autowired
    private ITeacherOutInRecordService teachertOutInRecordService;

    @Autowired
    private IWeChatService weChatService;

    @Autowired
    private CommonPropertiesConfig commonPropertiesConfig;

    @Autowired
    private WeChatUtil weChatUtil;

    @Autowired
    private IWechatMessageLogService wechatMessageLogService;

    @Test
    void test3(){
        LocalDateTime recentlyTime = LocalDateTime.now().withHour(8).withMinute(5).withSecond(0).withNano(0);
        long outInRecords = teachertOutInRecordService.count(
                new MPJLambdaWrapper<TeacherOutInRecord>()
                        .le(TeacherOutInRecord::getRecordTime, recentlyTime)
                        .eq(TeacherOutInRecord::getStatus, 1)
                        .eq(true,"DATE_FORMAT(record_time, '%Y-%m-%d')" , recentlyTime.toLocalDate())
                        .groupBy(TeacherOutInRecord::getUserId)
        );
        System.out.println(outInRecords);
    }
    @Test
    void test2(){
        String  wechatTemplate = "o-KboOcqcJ3YpjPN2xwgM_NcjN-0yzwWlDDXYfTM0Q4";
        WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
        weChatSendMessageDto.setTemplateId(wechatTemplate);
        JSONObject paramJson = new JSONObject();

        JSONObject thing6 = new JSONObject();
        thing6.put("value", "教职工");
        paramJson.put("thing6", thing6);

        JSONObject time11 = new JSONObject();
        time11.put("value", "2024-6-12 11:02:30");
        paramJson.put("time11", time11);

        JSONObject const23 = new JSONObject();
        const23.put("value", "上午考勤");
        paramJson.put("const23", const23);

        JSONObject character_string18 = new JSONObject();
        character_string18.put("value", "222");
        paramJson.put("character_string18", character_string18);

        JSONObject const3 = new JSONObject();
        const3.put("value", "出勤率 99%");
        paramJson.put("const3", const3);

        weChatSendMessageDto.setContent(paramJson);
        weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/teacher/index", commonPropertiesConfig.getDomainApp()));

        List<String> userList = new ArrayList<>();
        userList.add("oWZy-wec72H78ApagVBFomC5TNyw");
        userList.add("oWZy-wUTki8Vi7ao3Wn5JGNDauVI");
        for (String xjrUser : userList) {
            weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
            weChatSendMessageDto.setUserId(xjrUser);
            weChatService.sendTemplateMessage(weChatSendMessageDto);
        }


    }

    @Test
    void test(){
        doExecute();
    }

    public void doExecute(){
        LocalDateTime now = LocalDateTime.now();
        HolidayDate holidayDate = holidayDateService.getOne(
                new QueryWrapper<HolidayDate>().lambda()
                        .eq(HolidayDate::getDate, now.toLocalDate())
        );
        if(holidayDate != null && holidayDate.getWay() != null && holidayDate.getWay() != 0){
            return;
        }
        //查询今天的考勤规则
        List<AttendanceRuleDetails> ruleDetails = ruleCategoryService.getTodayRules();
        //获取最近的时间
        LocalDateTime recentlyTime = getRecentlyTime(ruleDetails, now);
        String wechatTemplate = weChatUtil.getAttendanceMsgLateTemplate();
        WechatMessageLog log = wechatMessageLogService.getOne(
                new QueryWrapper<WechatMessageLog>().lambda()
                        .select(WechatMessageLog.class, x -> VoToColumnUtil.fieldsToColumns(WechatMessageLog.class).contains(x.getProperty()))
                        .eq(WechatMessageLog::getSendTime, recentlyTime)
                        .eq(WechatMessageLog::getTemplateId, wechatTemplate)
        );
//        if(log != null){//已经推送过，不再进行推送
//            return;
//        }

        WechatMessageLog messageLog = new WechatMessageLog();
        messageLog.setTemplateId(wechatTemplate);
        messageLog.setSendTime(recentlyTime);

        List<AttendanceMessageSet> list = messageSetService.list(
                new QueryWrapper<AttendanceMessageSet>().lambda()
        );
        //判断是上午还是下午
        Integer timePeriod = null;
        String timePeriodStr = null;
        if(now.getHour() <= 12){
            timePeriod = 1;
            timePeriodStr = "上午考勤";
        }else if(now.getHour() <= 18){
            timePeriod = 2;
            timePeriodStr = "下午考勤";
        }else{
            timePeriod = 3;
            timePeriodStr = "晚上考勤";
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = recentlyTime.format(formatter);



        for (AttendanceMessageSet messageSet : list) {
            if(!messageSet.getTimePeriod().contains(timePeriod + "")){
                continue;
            }
            //查询需要通知的人
            List<XjrUser> userList = userService.list(
                    new MPJLambdaWrapper<XjrUser>()
                            .select(XjrUser::getId)
                            .select(XjrUser.class, x -> VoToColumnUtil.fieldsToColumns(XjrUser.class).contains(x.getProperty()))
                            .leftJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
                            .leftJoin(AttendanceMessageUserRelation.class, AttendanceMessageUserRelation::getUserId, XjrUser::getId)
                            .eq(UserRoleRelation::getRoleId, messageSet.getRoleType())
                            .eq(AttendanceMessageUserRelation::getAttendanceMessageSetId, messageSet.getId())
            );
            //没有需要通知的，直接跳过
            if(userList.isEmpty()){
                continue;
            }
            if(messageSet.getRoleType() != null && messageSet.getRoleType() == 2){
                //教师总人数
                long teacherCout = userService.count(
                        new MPJLambdaWrapper<XjrUser>()
                                .leftJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
                );
                //查询进入记录，就是实际到校的人数
                long outInRecords = teachertOutInRecordService.count(
                        new MPJLambdaWrapper<TeacherOutInRecord>()
                                .le(TeacherOutInRecord::getRecordTime, recentlyTime)
                                .eq(TeacherOutInRecord::getStatus, 1)
                );

                WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
                weChatSendMessageDto.setTemplateId(wechatTemplate);
                JSONObject paramJson = new JSONObject();

                JSONObject thing6 = new JSONObject();
                thing6.put("value", "教职工");
                paramJson.put("thing6", thing6);

                JSONObject time11 = new JSONObject();
                time11.put("value", format);
                paramJson.put("time11", time11);

                JSONObject const23 = new JSONObject();
                const23.put("value", timePeriodStr);
                paramJson.put("const23", const23);

                JSONObject character_string18 = new JSONObject();
                character_string18.put("value", teacherCout - outInRecords);
                paramJson.put("character_string18", character_string18);

                JSONObject character_string16 = new JSONObject();
                character_string16.put("value", teacherCout);
                paramJson.put("character_string16", character_string16);

                weChatSendMessageDto.setContent(paramJson);
                weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/teacher/index", commonPropertiesConfig.getDomainApp()));

                for (XjrUser xjrUser : userList) {
                    weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
                    weChatSendMessageDto.setUserId(xjrUser.getOpenId());
                    weChatService.sendTemplateMessage(weChatSendMessageDto);
                }
            }else if(messageSet.getRoleType() != null && messageSet.getRoleType() == 3){
                //教师总人数
                long teacherCout = userService.count(
                        new MPJLambdaWrapper<XjrUser>()
                                .leftJoin(BaseStudent.class, BaseStudent::getUserId, XjrUser::getId)
                );
                //查询进入记录，就是实际到校的人数
                long outInRecords = studentOutInRecordService.count(
                        new MPJLambdaWrapper<StudentOutInRecord>()
                                .le(StudentOutInRecord::getRecordTime, recentlyTime)
                                .eq(StudentOutInRecord::getStatus, 1)
                );

                WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
                weChatSendMessageDto.setTemplateId(weChatUtil.getAttenDanceWarnTemplate());
                JSONObject paramJson = new JSONObject();

                JSONObject thing6 = new JSONObject();
                thing6.put("value", "教职工");
                paramJson.put("thing6", thing6);

                JSONObject time11 = new JSONObject();
                time11.put("value", format);
                paramJson.put("time11", time11);

                JSONObject const23 = new JSONObject();
                const23.put("value", timePeriodStr);
                paramJson.put("const23", const23);

                JSONObject character_string18 = new JSONObject();
                character_string18.put("value", teacherCout - outInRecords);
                paramJson.put("character_string18", character_string18);

                JSONObject character_string16 = new JSONObject();
                character_string16.put("value", teacherCout);
                paramJson.put("const3", character_string16);

                weChatSendMessageDto.setContent(paramJson);
                weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/class/index", commonPropertiesConfig.getDomainApp()));

                for (XjrUser xjrUser : userList) {
                    weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
                    weChatSendMessageDto.setUserId(xjrUser.getOpenId());
                    weChatService.sendTemplateMessage(weChatSendMessageDto);
                }
            }
        }
        wechatMessageLogService.save(messageLog);
    }



    LocalDateTime getRecentlyTime(List<AttendanceRuleDetails> ruleDetails, LocalDateTime now){
        List<LocalDateTime> result = new ArrayList<>();
        for (AttendanceRuleDetails ruleDetail : ruleDetails) {
            if(ruleDetail.getIsAllowInOutSchool() != null && ruleDetail.getIsAllowInOutSchool() == 1
                    && ruleDetail.getIsAttendance() != null && ruleDetail.getIsAttendance() == 1){
                if(ruleDetail.getAmStartTime() != null){
                    LocalDateTime amStartTime = now.with(ruleDetail.getAmStartTime().toLocalTime());
                    result.add(amStartTime);
                }
                if(ruleDetail.getPmStartTime() != null){
                    LocalDateTime pmStartTime = now.with(ruleDetail.getPmStartTime().toLocalTime());
                    result.add(pmStartTime);
                }

                if(ruleDetail.getEveningStartTime() != null){
                    LocalDateTime eveningStartTime = now.with(ruleDetail.getEveningStartTime().toLocalTime());
                    result.add(eveningStartTime);
                }
            }
        }
        if(result.isEmpty()){
            return null;
        }
        Map<Long, LocalDateTime> timeMap = new HashMap<>();
        for (LocalDateTime localDateTime : result) {
            long between = ChronoUnit.SECONDS.between(now, localDateTime);
            timeMap.put(Math.abs(between), localDateTime);
        }
        List<Long> collect = timeMap.keySet().stream().collect(Collectors.toList());
        Collections.sort(collect, Long::compare);

        return timeMap.get(collect.get(0));
    }


    @Test
    void getRid(){
        String url = "https://api.weixin.qq.com/cgi-bin/openapi/rid/get?access_token=" + weChatUtil.getToken(WeChatType.WEWEB);
        JSONObject rid = new JSONObject();
        rid.put("rid", "6667fb56-0c3a8942-466e7d5e");
        String result = HttpUtil.post(url, JSONObject.toJSONString(rid));
        System.out.print(result);
    }
}