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

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.casic.missiles.core.common.service.ICommonPermissionService;
import com.casic.missiles.core.common.service.ICommonUserService;
import com.casic.missiles.modular.alarm.job.HandleAlarmJob;
import com.casic.missiles.modular.alarm.job.getDelayJob;
import com.casic.missiles.modular.alarm.service.IAlarmJobService;
import com.casic.missiles.core.datascope.DataScope;
import com.casic.missiles.core.util.EhcacheConstant;
import com.casic.missiles.core.util.ToolUtil;
import com.casic.missiles.modular.system.dao.AlarmJobMapper;
import com.casic.missiles.modular.system.dao.AlarmRecordsMapper;
import com.casic.missiles.modular.system.dto.SelectDto;
import com.casic.missiles.modular.system.dto.UserClientView;
import com.casic.missiles.modular.system.model.AlarmJob;
import com.casic.missiles.modular.system.model.BusWellInfo;
import com.casic.missiles.modular.system.model.User;
import com.casic.missiles.modular.system.service.IBusWellInfoService;
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 com.google.gson.GsonBuilder;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.*;

/**
 * <p>
 * 报警工单表 服务实现类
 * </p>
 *
 * @author casic123
 * @since 2019-05-17
 */
@Service
public class AlarmJobServiceImpl extends ServiceImpl<AlarmJobMapper, AlarmJob> implements IAlarmJobService {

    private static final Logger logger = LoggerFactory.getLogger(AlarmJobServiceImpl.class);

    @Value("${smartcity.leaderRoleName}")
    private String sLeader;
    @Value("${smartcity.memberRoleName}")
    private String sMember;
    @Value("${smartcity.appRoleName}")
    private String sApp;
    @Value("${smartcity.useOverTime")
    private String useOverTime;

    @Resource
    private AlarmRecordsMapper alarmRecordsMapper;
    //    @Resource
//    private ICommonPermissionService permissionService;
    @Resource
    private ICommonUserService iCommonUserService;
    @Resource
    private WebSocket webSocket;

    @Resource
    private IQuartzManager quartzManager;

    @Autowired IBusWellInfoService  busWellInfoService;

    @Override
    public List<Map<String, Object>> jobList(Page<Map<String, Object>> page, String keywords, String beginTime, String endTime, String jobStatus, String alarmType, String alarmContent, DataScope dataScope,Long userId) {
        alarmContent = converAlarmContent(alarmContent);
        List<Map<String, Object>> alarmJobList = this.baseMapper.jobList(page, keywords, beginTime, endTime, jobStatus, alarmType, alarmContent, dataScope,userId);return alarmJobList;
    }

    @Override
    public List<Map<String, Object>> jobListApp(Page<Map<String, Object>> page, String keywords, String beginTime, String endTime, String jobStatus, String alarmType, String alarmContent, Long deptId, Long userId, Long leaderId) {
        alarmContent = converAlarmContent(alarmContent);
        List<Map<String, Object>> alarmJobList = this.baseMapper.jobListApp(page, keywords, beginTime, endTime, jobStatus, alarmType, alarmContent, deptId, userId, leaderId);
        return alarmJobList;
    }

    @Override
    public List<Map<String, Object>> jobListDelayRe(Page<Map<String, Object>> page, String keywords, String beginTime, String endTime, String alarmType, String alarmContent, DataScope dataScope,Long userId) {
        alarmContent = converAlarmContent(alarmContent);
        List<Map<String, Object>> alarmJobList = this.baseMapper.jobListDelayRe(page, keywords, beginTime, endTime, alarmType, alarmContent, dataScope,userId);
        return alarmJobList;
    }

    @Override
    public List<Map<String, Object>> jobListDelayReApp(Page<Map<String, Object>> page, String keywords, String beginTime, String endTime, String alarmType, String alarmContent, Long deptId, Long userId, Long leaderId) {
        alarmContent = converAlarmContent(alarmContent);
        List<Map<String, Object>> alarmJobList = this.baseMapper.jobListDelayReApp(page, keywords, beginTime, endTime, alarmType, alarmContent, deptId, userId, leaderId);
        return alarmJobList;
    }

    @Override
    public List<Map<String, Object>> jobListDelayPro(Page<Map<String, Object>> page, String keywords, String beginTime, String endTime, String alarmType, String alarmContent, DataScope dataScope,Long userId) {
        alarmContent = converAlarmContent(alarmContent);
        List<Map<String, Object>> alarmJobList = this.baseMapper.jobListDelayPro(page, keywords, beginTime, endTime, alarmType, alarmContent, dataScope,userId);
        return alarmJobList;
    }

    @Override
    public List<Map<String, Object>> jobListDelayProApp(Page<Map<String, Object>> page, String keywords, String beginTime, String endTime, String alarmType, String alarmContent, Long deptId, Long userId, Long leaderId) {
        alarmContent = converAlarmContent(alarmContent);
        List<Map<String, Object>> alarmJobList = this.baseMapper.jobListDelayProApp(page, keywords, beginTime, endTime, alarmType, alarmContent, deptId, userId, leaderId);
        return alarmJobList;
    }

    @Override
    public List<Map<String, Object>> jobListSearch(Page<Map<String, Object>> page, String keywords, String alarmLevel, String alarmContent, String jobStatus, String beginTime, String endTime, String getJobBeginTime, String getJobEndTime, String shouldGetBeginTime, String shouldGetEndTime, String handleJobBeginTime, String handleJobEndTime, String shouldHandleBeginTime, String shouldHandleEndTime, DataScope dataScope,Long userId) {
        alarmContent = converAlarmContent(alarmContent);
        List<Map<String, Object>> alarmJobList = this.baseMapper.jobListSearch(page, keywords, alarmLevel, alarmContent, jobStatus, beginTime, endTime, getJobBeginTime, getJobEndTime, shouldGetBeginTime, shouldGetEndTime, handleJobBeginTime, handleJobEndTime, shouldHandleBeginTime, shouldHandleEndTime, dataScope,userId);
        return alarmJobList;
    }

    @Override
    public List<Map<String, Object>> jobListSearchApp(Page<Map<String, Object>> page, String keywords, String alarmLevel, String alarmContent, String jobStatus, String beginTime, String endTime, String getJobBeginTime, String getJobEndTime, String shouldGetBeginTime, String shouldGetEndTime, String handleJobBeginTime, String handleJobEndTime, String shouldHandleBeginTime, String shouldHandleEndTime, Long deptId, Long userId, Long leaderId) {
        alarmContent = converAlarmContent(alarmContent);
        List<Map<String, Object>> alarmJobList = this.baseMapper.jobListSearchApp(page, keywords, alarmLevel, alarmContent, jobStatus, beginTime, endTime, getJobBeginTime, getJobEndTime, shouldGetBeginTime, shouldGetEndTime, handleJobBeginTime, handleJobEndTime, shouldHandleBeginTime, shouldHandleEndTime, deptId, userId, leaderId);
        return alarmJobList;
    }

    private String converAlarmContent(String alarmContent){
        if(ToolUtil.isEmpty(alarmContent)){
            return alarmContent;
        }else {
            return EhcacheConstant.retBean().getAlarmContentName(Integer.valueOf(alarmContent));
        }
    }

    @Override
    public List<Map<String,Object>> jobInfo(int id, DataScope dataScope, Long personId)
    {
        List<Map<String,Object>> job = this.baseMapper.jobInfo(id,dataScope,personId);
        return job;
    }

    @Override
    public Map<String, Object> countByJobStatus(long deptId,int spanDays) {
        return this.baseMapper.countByJobStatus(deptId,spanDays);
    }

    @Override
    public Map<String, Object> countMyJob(long userId,long deptId,int spanDays) {
        return this.baseMapper.countMyJob(userId,deptId,spanDays);
    }

    @Override
    public boolean getJob(int id, long personId) {

        Calendar now = Calendar.getInstance();
        Date getTime = now.getTime();
        if(isWeekend(now)){
            now.add(Calendar.WEEK_OF_YEAR, 1);
            now.set(Calendar.DAY_OF_WEEK ,Calendar.TUESDAY);
            now.set(Calendar.HOUR_OF_DAY,8);
            now.set(Calendar.MINUTE,0);
            now.set(Calendar.SECOND,0);
        }else {
            now.add(Calendar.HOUR, 24);
            while(isWeekend(now)){
                now.add(Calendar.HOUR, 24);
            }
        }
        Date shouldHandleTime = now.getTime();
        if(Boolean.getBoolean(useOverTime)){
            System.out.println(shouldHandleTime);
            String jobName = "getJobDelay" + id;
            Map<String,Object> map = new HashMap<>();
            map.put("jobId",id);
            map.put("iAlarmJobService",this);
            map.put("iCommonUserService",iCommonUserService);
            map.put("iQuartzManager",quartzManager);
            map.put("webSocket",webSocket);
            quartzManager.addJob(jobName,getDelayJob.class,shouldHandleTime,map);
        }

        return this.baseMapper.getJob(id,personId,getTime,shouldHandleTime);
    }

    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;
        }
    }

    @Override
    public boolean confirmJob(int id,long personId, String firstState, String firstStatePhotos, String needHandle) {
        if ("1".equals(needHandle)){
            return this.baseMapper.confirmJob(id,personId, firstState, firstStatePhotos, needHandle);
        } else {
            return this.baseMapper.confirmOverJobAndAlarm(id, personId,firstState, firstStatePhotos);
        }
    }

    @Override
    public boolean transferJob(int id, long transferPerson,String flowRec) {
        return this.baseMapper.transferJob(id, transferPerson,flowRec);
    }

    @Override
    public boolean saveJob(int id, String handleMessage, String handlePhotos) {
        return this.baseMapper.saveJob(id, handleMessage, handlePhotos);
    }

    @Override
    public boolean overJob(int id,long personId, String handleMessage, String handlePhotos) {
        return this.baseMapper.overJobAndAlarm(id, personId,handleMessage, handlePhotos);
//        return this.baseMapper.overJob(id, personId,handleMessage, handlePhotos);
    }
    @Override
    public boolean overAlarm(int jobId) {
        return this.baseMapper.overAlarm(jobId);
//        return this.baseMapper.overJob(id, personId,handleMessage, handlePhotos);
    }

    @Override
    public boolean handleJob(int id,long personId) {
        return this.baseMapper.handleJob(id,personId);
    }

    @Override
    public boolean checkJobStatus(String jobStatus) {
        if(ToolUtil.isEmpty(jobStatus)){
            return false;
        }else{
            return "1".equals(jobStatus) || "2".equals(jobStatus) || "3".equals(jobStatus);
        }
    }

    @Override
    public List<UserClientView> selectUserByWellCode(String wellCode) {
        return this.baseMapper.selectUserByWellCode(wellCode);
    }



    public List<SelectDto> selectRoles() {
        return this.baseMapper.selectRoles();
    }
    public List<Long> selectUseIds(List<Long> roleIds) {
        return this.baseMapper.selectUseIds(roleIds);
    }

    @Override
    public boolean checkPcRole(List<String> roleTips) {
        List<String> roleList = new ArrayList<>(roleTips);
        Iterator<String> it = roleList.iterator();
        while (it.hasNext()){
            String role = it.next();
            if(role.equals(sApp)||role.equals(sLeader)||role.equals(sMember)){
                it.remove();
            }
        }
        return roleList.size()>0;
    }

    @Override
    public Integer countByDataScope(DataScope dataScope, String alarmType, String jobStatus, String beginTime,String endTime) {
        List<Map<String,Object>> res = this.baseMapper.countByDataScope(dataScope,alarmType,jobStatus,beginTime,endTime);
        return res.size();
    }

    @Override
    public Integer countByResponse(String alarmType, String jobStatus, Long deptId, String beginTime,String endTime) {
        return this.baseMapper.countByResponse(alarmType,jobStatus,deptId,beginTime,endTime);
    }

    @Override
    public Integer countByUser(String alarmType, String jobStatus, Long userId, String beginTime,String endTime) {
        return this.baseMapper.countByUser(alarmType,jobStatus,userId,beginTime,endTime);
    }


    @Override
    public void updateSinkJob(String id, String msg,String wellCode) {
        List<UserClientView> userClientViewList = new ArrayList<>();
        List<SelectDto> selectDtoList = selectRoles();
        EntityWrapper<BusWellInfo> busWellInfoEntityWrapper = new EntityWrapper<>();
        busWellInfoEntityWrapper.eq("WELL_CODE",wellCode);
        BusWellInfo busWellInfo = busWellInfoService.selectOne(busWellInfoEntityWrapper);
        if(busWellInfo!=null&&ToolUtil.isNotEmpty(busWellInfo.getDeptid())){
            List<Long> roleids= new ArrayList<>();
            for(SelectDto selectDto:selectDtoList){
                if(ToolUtil.isNotEmpty(selectDto.getName())
                  && Arrays.asList(selectDto.getName().split(",")).contains(busWellInfo.getDeptid())){
                    roleids.add(selectDto.getId());
                }
            }
            if(roleids.size()>0){
                List<Long> useIds = selectUseIds(roleids);
                for(Long useId:useIds){
                    UserClientView userClientView = new UserClientView();
                    userClientView.setClientid(useId.toString());
                    userClientView.setId(useId.toString());
                    userClientViewList.add(userClientView);
                }
            }
        }

        if(!("null".equals(id))){
            AlarmJob alarmJob = this.baseMapper.selectById(id);
            sendJob(id, alarmJob, userClientViewList);//推送工单至app和pc端
        }
        if(StringUtils.isNotBlank(msg)){
            sendAlarm(msg, userClientViewList);//推送告警至app和pc端
        }

    }


    public void sendAlarm(String msg, List<UserClientView> userClientViewList) {
        List<String> clientIds = new ArrayList<>();
        List<String> userIds = new ArrayList<>();
        for (UserClientView userClientView : userClientViewList) {
            if (ToolUtil.isNotEmpty(userClientView.getClientid())) {
                clientIds.add(userClientView.getClientid());
            }
            if (ToolUtil.isNotEmpty(userClientView.getId())) {
                userIds.add(userClientView.getId());
            }
        }
        if (clientIds.size() > 0) {
            IPushResult pushResult = PushList.pushToUser(clientIds, "告警提醒", msg);
            if ("ok".equals(pushResult.getResponse().get("result").toString())) {
                logger.info("告警消息app端推送成功:" + msg);
            } else {
                logger.info("告警消息app端推送失败:" + msg);
            }
        } else {
            logger.info("告警消息app端找不到责任人，未推送:" + msg);
        }
        // PC推送,推给信息办
//            List<User> userList = permissionService.getRoleUsersByTips("1178242562491285506",null,false);
        EntityWrapper wrapper = new EntityWrapper();
        wrapper.eq("DEPTID", "1178242562491285506");
        List<User> userList = iCommonUserService.selectUsersList(wrapper, null);
        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, new GsonBuilder().create().toJson(map));
        } else {
            logger.info("告警消息找不到责任人，pc端未推送:" + msg);
        }

    }

    public void sendJob(String id, AlarmJob alarmJob, List<UserClientView> userClientViewList) {

        Calendar now = Calendar.getInstance();
        if (isWeekend(now)) {
            now.add(Calendar.WEEK_OF_YEAR, 1);
            now.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            now.set(Calendar.HOUR_OF_DAY, 10);//默认8点上班
            now.set(Calendar.MINUTE, 0);
            now.set(Calendar.SECOND, 0);
        } else {
            try {
                if (isTimeRange()) {
                    now.add(Calendar.HOUR_OF_DAY, 2);
                } else {
                    now.set(Calendar.HOUR_OF_DAY, 10);//默认8点上班
                    now.set(Calendar.MINUTE, 0);
                    now.set(Calendar.SECOND, 0);
                    if (!compareNoon()) {
                        now.add(Calendar.DAY_OF_MONTH, +1);

                    }
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
        Date shouldHandleTime = now.getTime();
        if(Boolean.getBoolean(useOverTime)) {
            System.out.println(shouldHandleTime);
            String jobName = "getJobDelay" + id;
            Map<String, Object> map = new HashMap<>();
            map.put("jobId", id);
            map.put("iAlarmJobService", this);
            map.put("iCommonUserService", iCommonUserService);
            map.put("iQuartzManager", quartzManager);
            map.put("webSocket", webSocket);
            map.put("userClientViewList", userClientViewList);
            quartzManager.addJob(jobName, HandleAlarmJob.class, shouldHandleTime, map);
            alarmJob.setShouldGetTime(shouldHandleTime);
        }

        this.baseMapper.updateById(alarmJob);
    }

    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;
        }
    }

    @Override
    public String selectClientIdByUser(Long userId) {
        return this.baseMapper.selectClientIdByUser(userId);
    }
}
