package cn.iocoder.yudao.module.system.job.attendance;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.framework.common.Constants;
import cn.iocoder.yudao.framework.common.enums.SocialTypeEnum;
import cn.iocoder.yudao.framework.common.template.WxMaMsgTemplateUtils;
import cn.iocoder.yudao.framework.common.template.dto.CheckInReminderDTO;
import cn.iocoder.yudao.framework.common.template.vo.SubscribeMessageReqDTO;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi;
import cn.iocoder.yudao.module.system.controller.admin.attendance.dto.AttendanceWorkDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.punchrecord.AttendancePunchRecordDO;
import cn.iocoder.yudao.module.system.dal.dataobject.auth.AdminOauthUserOtherInfoDO;
import cn.iocoder.yudao.module.system.service.attendance.punchrecord.AttendancePunchRecordService;
import cn.iocoder.yudao.module.system.service.auth.AdminOauthUserOtherInfoService;
import cn.iocoder.yudao.module.system.service.auth.dto.AdminOauthUserOtherInfoDTO;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class RemindJob {
    @Resource
    private AttendancePunchRecordService attendancePunchRecordService;
    @Resource
    private SubscribeMessageSendApi subscribeMessageSendApi;
    @Resource
    private AdminUserService adminUserService;
    @Resource
    private AdminOauthUserOtherInfoService adminOauthUserOtherInfoService;

    // TODO: 2024/4/22  - 考勤提醒 每10分钟执行一次
    @XxlJob("remindJob")
    @TenantJob // --- ⚠️ 这个注解 会将租户列表拉出来 完了后逐个租户执行 定时任务需要注意
    public ReturnT<String> execute() throws Exception {
        // -- 获取当天以及明天的未打卡并且未提醒记录
        //未提醒列表
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime futureTime = localDateTime.plusMinutes(15);

        List<AttendancePunchRecordDO> attendancePunchRecordDOS = attendancePunchRecordService.getNotReminded(localDateTime);
        if (attendancePunchRecordDOS.isEmpty()) {
            return ReturnT.SUCCESS;
        }

        //还有10分钟就要上班了，别忘记打卡哦～
        //幸苦一天了，研发部全体人员提醒您，记得打卡哦～
        Map<Long, AttendanceWorkDTO> map = new HashMap<>();
        //打卡时间 - 15分钟之后是否是 大于打卡时间 - 是的话 - 把用户id拿出来 组装好消息发送
        List<Long> editIdsList = new ArrayList<>();
        for (AttendancePunchRecordDO attendancePunchRecordDO : attendancePunchRecordDOS) {
            if (attendancePunchRecordDO.getWorkType().equals(Constants.ZERO) && futureTime.isAfter(attendancePunchRecordDO.getShouldPunchTime())) {
                AttendanceWorkDTO dto = new AttendanceWorkDTO();
                dto.setWorkTypeStr("上班打卡");
                dto.setData(String.format("还有%s钟就要上班了，别忘记打卡哦～",
                        DateUtil.formatBetween(LocalDateTimeUtil.between(localDateTime, attendancePunchRecordDO.getShouldPunchTime()).toMillis(), BetweenFormatter.Level.MINUTE)));
                map.put(attendancePunchRecordDO.getUserId(), dto);
                editIdsList.add(attendancePunchRecordDO.getId());
            } else if (attendancePunchRecordDO.getWorkType().equals(Constants.ONE) && localDateTime.isAfter(attendancePunchRecordDO.getShouldPunchTime())) {
                AttendanceWorkDTO dto = new AttendanceWorkDTO();
                dto.setWorkTypeStr("下班打卡");
                dto.setData("工作幸苦了，记得打卡哦～");
                map.put(attendancePunchRecordDO.getUserId(), dto);
                editIdsList.add(attendancePunchRecordDO.getId());
            }
        }
        //获取到所有的用户id
        if (MapUtil.isEmpty(map)) {
            return ReturnT.SUCCESS;
        }
        List<Long> userIds = new ArrayList<>(map.keySet());
        List<AdminOauthUserOtherInfoDO> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userIds)) {
            list = adminOauthUserOtherInfoService.getOpenIdByCondition(new AdminOauthUserOtherInfoDTO()
                    .setSocialType(SocialTypeEnum.WECHAT_MINI_APP.getType())
                    .setUserIds(userIds));
        }
        List<SubscribeMessageReqDTO> dtos = new ArrayList<>();
        for (AdminOauthUserOtherInfoDO user : list) {
            AttendanceWorkDTO attendanceWorkDTO = map.get(user.getUserId());
            SubscribeMessageReqDTO dto = new WxMaMsgTemplateUtils().convertCheckInReminder(new CheckInReminderDTO()
                    .setOpenId(user.getOpenId())
                    .setCheckInType(attendanceWorkDTO.getWorkTypeStr())
                    .setComment(attendanceWorkDTO.getData())
                    .setPage("subPages/attendance/index"));
            dtos.add(dto);
        }
        if (CollectionUtil.isNotEmpty(dtos)) {
            for (SubscribeMessageReqDTO dto : dtos) {
                subscribeMessageSendApi.sendMaMsg(dto);
            }
        }
        if (CollectionUtil.isNotEmpty(editIdsList)) {
            attendancePunchRecordService.update(new AttendancePunchRecordDO().setRemindFlag(Constants.TRUE),
                    new LambdaQueryWrapper<AttendancePunchRecordDO>()
                            .in(AttendancePunchRecordDO::getId, editIdsList));
        }
        // 返回执行成功
        return ReturnT.SUCCESS;
    }


}













