package com.fjhx.oa.utils;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fjhx.common.enums.PushBusinessTypeEnum;
import com.fjhx.oa.entity.schedule.po.ScheduleDetails;
import com.fjhx.oa.entity.schedule.po.ScheduleInfo;
import com.fjhx.oa.service.schedule.ScheduleDetailsService;
import com.fjhx.oa.service.schedule.ScheduleInfoService;
import com.fjhx.socket.core.PushTypeEnum;
import com.fjhx.socket.core.WebSocketPush;
import com.ruoyi.framework.mybatis.holder.TenantHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 工作日程消息通知
 */

@Configuration
@EnableScheduling
public class Notice {
    private static Map<Long, ScheduleInfo> scheduleInfoMap = new ConcurrentHashMap<>();
    private static SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");

    @Autowired
    ScheduleInfoService scheduleInfoService;
    @Autowired
    ScheduleDetailsService scheduleDetailsService;

    /**
     * 启动时和每天0点 查询当天的日程
     */
    @PostConstruct
    @Scheduled(cron = "0 0 0 * * ?")
    public void getNoticeList() {
        TenantHolder.setIgnore(true);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("(date( start_date ) = curdate())", 1);
        List<ScheduleInfo> scheduleInfos0 = scheduleInfoService.list(queryWrapper);
        scheduleInfoMap = scheduleInfos0.stream().collect(Collectors.groupingBy(ScheduleInfo::getId,
                Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
        TenantHolder.clear();
    }


    /**
     * 每10秒检查一次
     */
    @Scheduled(cron = "0/10 * * * * ?")
    public void sendNoticeTime() {
        TenantHolder.setIgnore(true);
        List<ScheduleInfo> scheduleInfos = new ArrayList<>();
//        for (Map.Entry<Long, ScheduleInfo> entry : scheduleInfoMap.entrySet()) {
        Iterator<Map.Entry<Long, ScheduleInfo>> it = scheduleInfoMap.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<Long, ScheduleInfo> entry = it.next();

            ScheduleInfo scheduleInfo = entry.getValue();
            Date startDate = scheduleInfo.getStartDate();
            Date date = new Date();
            long diff = startDate.getTime() - date.getTime();
            long min = (long) Math.ceil(diff / 60.0 / 1000.0);
            if (min < 0) {
//                scheduleInfoMap.remove(scheduleInfo.getId());
                it.remove();
            }
            //根据类型判断提前多少分钟通知
            if (min == scheduleInfo.getNoticeType()) {
//                scheduleInfoMap.remove(scheduleInfo.getId());
                it.remove();
                scheduleInfos.add(scheduleInfo);
            }
        }
        //查询参与者并发送通知
        if (ObjectUtil.isNotEmpty(scheduleInfos)) {
            Map<Long, ScheduleInfo> scheduleInfoMap1 = scheduleInfos.stream().collect(Collectors.groupingBy(ScheduleInfo::getId,
                    Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
            List<Long> scheduleInfoIds = scheduleInfos.stream().map(ScheduleInfo::getId).collect(Collectors.toList());
            List<ScheduleDetails> scheduleDetailsList = scheduleDetailsService.list(q -> q.in(ScheduleDetails::getScheduleInfoId, scheduleInfoIds));
            for (ScheduleDetails scheduleDetails : scheduleDetailsList) {
                // 发送消息
                ScheduleInfo scheduleInfo = scheduleInfoMap1.get(scheduleDetails.getScheduleInfoId());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String msg = String.format("您的日程<%s>将于%s开始。", scheduleInfo.getTitle(), sdf.format(scheduleInfo.getStartDate()));

                Map<String, Object> msgMap = new HashMap<>();
                msgMap.put("businessId", scheduleInfo.getId());
                msgMap.put("msg", msg);
                // WebSocketServer.sendInfo(scheduleDetails.getParticipantId(), 1, msgMap);

                WebSocketPush.byUser(
                        PushTypeEnum.PUSH_NOTIFICATION,
                        scheduleDetails.getParticipantId(),
                        msg,
                        PushBusinessTypeEnum.SCHEDULE_REMINDER.getType(),
                        msgMap
                );
            }
        }
        TenantHolder.clear();
    }

    /**
     * 判断日期日程的开始时间是否是今天，如果是就添加到待发送消息队列
     */
    public static void updateNoticeList(ScheduleInfo scheduleInfo) {
        Date now = new Date();
        //获取今天的日期
        String nowDay = sf.format(now);
        //对比的时间
        String day = sf.format(scheduleInfo.getStartDate());
        if (day.equals(nowDay)) {
            scheduleInfoMap.put(scheduleInfo.getId(), scheduleInfo);
        } else {
            scheduleInfoMap.remove(scheduleInfo.getId());
        }
    }

    /**
     * 删除日程的通知计划
     */
    public static void deleteNoticeList(Long id) {
        scheduleInfoMap.remove(id);
    }
}
