package com.casic.missiles.modular.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.casic.missiles.core.application.context.AbstractPermissionContext;
import com.casic.missiles.modular.alarm.job.DelayJob;
import com.casic.missiles.modular.alarm.job.HandleAlarmJob;
import com.casic.missiles.modular.alarm.service.IAlarmJobService;
import com.casic.missiles.modular.system.dao.AlarmJobMapper;
import com.casic.missiles.modular.system.dao.MessagePusherMapper;
import com.casic.missiles.modular.system.model.AlarmJob;
import com.casic.missiles.modular.system.model.User;
import com.casic.missiles.modular.system.model.UserPush;
import com.casic.missiles.modular.system.service.MessagePusherService;
import com.casic.missiles.modular.system.util.PushList;
import com.casic.missiles.modular.system.util.WebSocket;
import com.casic.missiles.quartz.service.IQuartzManager;
import com.gexin.rp.sdk.base.IPushResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MessagePusherImpl extends ServiceImpl<MessagePusherMapper, UserPush> implements MessagePusherService {

    @Resource
    private WebSocket webSocket;
    @Autowired
    private DataScopeBuilder dataScopeBuilder;
    @Resource
    private AlarmJobMapper alarmJobMapper;
    @Autowired
    private IAlarmJobService alarmJobService;
    @Resource
    private IQuartzManager quartzManager;
    @Resource
    private AbstractPermissionContext iCommonUserService;

    @Value("${smartcity.useOverTime}")
    private String useOverTime;

    @Override
    public boolean getJob(Long id, long deptid,Long personId) {
        Calendar now = Calendar.getInstance();
        Date getTime = now.getTime();
        now.add(Calendar.HOUR, 4);
        Date shouldHandleTime = now.getTime();
        if (useOverTime.equals("true")) {
            System.out.println(shouldHandleTime);
            String jobName = "getJobDelay" + id;
            Map<String, Object> map = new HashMap<>();
            map.put("jobId", id);
            map.put("iAlarmJobService", alarmJobService);
            map.put("iCommonUserService", iCommonUserService);
            map.put("iQuartzManager", quartzManager);
            map.put("webSocket", webSocket);
            quartzManager.addJob(jobName, DelayJob.class, shouldHandleTime, map);
        }
        return this.baseMapper.getJob(id, personId, getTime, shouldHandleTime);
    }

    @Override
    public void updateSinkJob(String id, String msg) {
        if (!(StrUtil.isEmpty(id))) {
            AlarmJob alarmJob = alarmJobMapper.selectById(Long.valueOf(id));
            if (!ObjectUtil.isEmpty(alarmJob)) {
                Map<String, Long> deptMap = this.baseMapper.getDeptIdsByDevcode(alarmJob.getDevcode());
                if (!ObjectUtil.isEmpty(deptMap)){
                    List<String> userClientList = responDeptProvider(deptMap.get("ownerDeptId"));
                    sendJob(id, alarmJob, userClientList);//推送工单至app和pc端
                    if (StrUtil.isNotBlank(msg)) {
                        sendAlarm(id,msg, deptMap.get("deptid"), userClientList, alarmJob.getDevcode());//推送告警至app和pc端
                    }
                }
            }
        }
    }

    @Override
    public void registerGeTui(Long userId, String clientid) {
        UserPush userPush = new UserPush();
        userPush.setType("GT");
        userPush.setUserId(userId);
        userPush.setClientId(clientid);
        UserPush old = this.baseMapper.getPushByUserId(userId, userPush.getType());
        userPush.setUpdateTime(new Date());
        if (!ObjectUtil.isEmpty(old)) {
            userPush.setId(old.getId());
            this.baseMapper.updateById(userPush);
        } else {
            userPush.setCreateTime(new Date());
            this.baseMapper.insert(userPush);
        }
    }

    private void sendAlarm(String jobId,String msg, Long deptId, List<String> clientIdlist, String devcode) {
        List<String> userIds = new ArrayList<>();
        String appMsg = "设备编号[" + devcode + "]发生" + msg+",工单编号为["+jobId+"]";
        if (clientIdlist.size() > 0) {
            IPushResult pushResult = PushList.pushToUser(clientIdlist, "新的工单任务", appMsg);
            if ("ok".equals(pushResult.getResponse().get("result").toString())) {
                log.info("告警消息app端推送成功:" + appMsg+"：推送人第一个人clienId"+clientIdlist.get(0));
            } else {
                log.info("告警消息app端推送失败:" + appMsg);
            }
        } else {
            log.info("告警消息app端找不到责任人，未推送:" + appMsg);
        }
        // PC推送
        List<User> userList = dataScopeBuilder.DataScopeProvider(deptId);
        for (User user : userList) {
            userIds.add(user.getId().toString());
        }
        if (userIds.size() > 0) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("message", msg);
            map.put("type", "alarm");
            webSocket.sendListMessage(userIds, JSON.toJSONString(map));
        } else {
            log.info("告警消息找不到责任人，pc端未推送:" + msg);
        }

    }

    private void sendJob(String id, AlarmJob alarmJob, List<String> userClientList) {
        Calendar handlerTime = Calendar.getInstance();
        handlerTime.add(Calendar.HOUR, 1);
        Date shouldHandleTime = handlerTime.getTime();
        if (useOverTime.equals("true")) {
            System.out.println(shouldHandleTime);
            String jobName = "getJobDelay" + id;
            Map<String, Object> map = new HashMap<>();
            map.put("jobId", Long.valueOf(id));
            map.put("iAlarmJobService", alarmJobService);
            map.put("iCommonUserService", iCommonUserService);
            map.put("iQuartzManager", quartzManager);
            map.put("webSocket", webSocket);
            map.put("clientIds", userClientList);
            quartzManager.addJob(jobName, HandleAlarmJob.class, shouldHandleTime, map);
            alarmJob.setShouldGetTime(shouldHandleTime);
        }
        alarmJobMapper.updateById(alarmJob);
    }

    private boolean isWeekend(Calendar cal) {
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isTimeRange() throws ParseException {//接单时间默认朝八晚八
        SimpleDateFormat df = new SimpleDateFormat("HH:mm");
        Date now = df.parse(df.format(new Date()));
        Date begin = df.parse("8:00");
        Date end = df.parse("20:00");
        Calendar nowTime = Calendar.getInstance();
        nowTime.setTime(now);
        Calendar beginTime = Calendar.getInstance();
        beginTime.setTime(begin);
        Calendar endTime = Calendar.getInstance();
        endTime.setTime(end);
        if (nowTime.before(endTime) && nowTime.after(beginTime)) {
            return true;
        } else {
            return false;
        }
    }

    public boolean compareNoon() {
        Date date = new Date();
        SimpleDateFormat df = new SimpleDateFormat("HH");
        String str = df.format(date);
        int a = Integer.parseInt(str);
        if (a >= 0 && a <= 12) {
            return true;
        } else {
            return false;
        }
    }

    public List<String> responDeptProvider(Long ownerDeptId) {
        List<Long> userIdList = this.baseMapper.getUserIdList(ownerDeptId);
        List<String> clientList = this.clientProvider(userIdList);
        return clientList;
    }


    public List<String> clientProvider(List<Long> userIdList) {
        List<UserPush> allPushList = this.baseMapper.getUserPush();
        Map<Long, String> pushMap = allPushList.stream().collect(
                Collectors.toMap(UserPush::getUserId, UserPush::getClientId)
        );
        List<String> clientLists = new ArrayList<>();
        userIdList.forEach(
                userId -> {
                    if (pushMap.containsKey(Long.valueOf(String.valueOf(userId)))) {
                        clientLists.add(pushMap.get(Long.valueOf(String.valueOf(userId))));
                    }
                }
        );
        return clientLists;
    }


}
