package com.mortals.xhx.daemon.task;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.xhx.common.code.FinishMethodEnum;
import com.mortals.xhx.common.code.MeetStatusEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.keys.RedisCacheKeys;
import com.mortals.xhx.common.pdu.UploadDeviceReq;
import com.mortals.xhx.feign.device.IDeviceMessageFeign;
import com.mortals.xhx.module.basic.model.BasicSetEntity;
import com.mortals.xhx.module.basic.service.BasicSetService;
import com.mortals.xhx.module.metting.model.MettingRecordEntity;
import com.mortals.xhx.module.metting.model.MettingRecordQuery;
import com.mortals.xhx.module.metting.service.MettingRecordService;
import com.mortals.xhx.module.room.model.RoomDeviceEntity;
import com.mortals.xhx.module.room.model.RoomDeviceQuery;
import com.mortals.xhx.module.room.model.RoomEntity;
import com.mortals.xhx.module.room.service.RoomDeviceService;
import com.sun.org.apache.xerces.internal.dom.PSVIAttrNSImpl;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 会议室切换状态
 */
@Slf4j
@Service("MeetSwitchTaskTask")
public class MeetSwitchTaskImpl implements ITaskExcuteService {

    @Autowired
    private MettingRecordService mettingRecordService;

    @Autowired
    private BasicSetService basicSetService;
    @Autowired
    private IDeviceMessageFeign messageFeign;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private RoomDeviceService roomDeviceService;

    @Override
    public void excuteTask(ITask task) throws AppException {
        log.debug("会议室切换状态");
        BasicSetEntity basicSetEntity = basicSetService.selectOne(new BasicSetEntity());
        if (ObjectUtils.isEmpty(basicSetEntity)) {
            log.info("基础未配置");
            return;
        }
        swicthMeet(basicSetEntity);
        log.debug("会议室切换状态完成");
    }


    private void swicthMeet(BasicSetEntity basicSetEntity) {
        if (!ObjectUtils.isEmpty(basicSetEntity.getPreMeetStart()) && basicSetEntity.getPreMeetStart() > 0) {
            //会议开始前几分钟 通知设备进行数据更新
            MettingRecordQuery mettingRecordQuery = new MettingRecordQuery();
            //mettingRecordQuery.setFinishMethod(FinishMethodEnum.自动结束.getValue());
            mettingRecordQuery.setMeetStatus(MeetStatusEnum.等待中.getValue());
            List<MettingRecordEntity> recordEntities = mettingRecordService.find(mettingRecordQuery);
            for (MettingRecordEntity recordEntity : recordEntities) {
                long between = DateUtil.between(new Date(), recordEntity.getMeetTimeStart(), DateUnit.MINUTE);
                if (between <= basicSetEntity.getPreMeetStart()) {
                    RoomDeviceQuery roomDeviceQuery = new RoomDeviceQuery();
                    roomDeviceQuery.setRoomId(recordEntity.getRoomId());
                    RoomDeviceEntity roomDeviceEntity = roomDeviceService.selectOne(roomDeviceQuery);
                    if (ObjectUtils.isEmpty(roomDeviceEntity)) return;
                    //还需满足当前进行中的会议 是否已经结束超时 存在时才推送消息

                    mettingRecordQuery = new MettingRecordQuery();
                    mettingRecordQuery.setMeetStatus(MeetStatusEnum.进行中.getValue());
                    mettingRecordQuery.setRoomId(recordEntity.getRoomId());

                    MettingRecordEntity mettingRecordEntity = mettingRecordService.selectOne(mettingRecordQuery);
                    if (!ObjectUtils.isEmpty(mettingRecordEntity)) {

                        //判断会议是提前结束 还是自动结束
                        if (basicSetEntity.getMeetEnd() == YesNoEnum.YES.getValue()) {
                            long mettingBetween = DateUtil.between(mettingRecordEntity.getMeetTimeEnd(), new Date(), DateUnit.MINUTE);
                            if (mettingBetween <= basicSetEntity.getPostMeetStart()) {
                                log.info("当前进行中的会议未结束，不推送下一个会议消息");
                                return;
                            }
                        }

                        if (basicSetEntity.getPostMeetStart() > 0) {
                            //查看结束通知是否设置
                            long mettingBetween = DateUtil.between(mettingRecordEntity.getMeetTimeStart(), new Date(), DateUnit.MINUTE);
                            if (mettingBetween <= basicSetEntity.getPostMeetStart()) {
                                log.info("当前进行中的会议未结束，不推送下一个会议消息");
                                return;
                            }
                        }
                    }

                    //通知设备进行数据更新
                    long expire = between * 60;
                    if(expire==0){
                        expire=60;
                    }
                    log.info("会议redis 设置过期时间:{}", expire);
                    try {
                        boolean setnx = cacheService.setnx(RedisKey.KEY_METTING_START_CACHE, recordEntity.getId(), expire);
                        if (setnx) {
                            UploadDeviceReq uploadDeviceReq = new UploadDeviceReq();
                            uploadDeviceReq.setDeviceCodeList(Arrays.asList(roomDeviceEntity.getDeviceCode()));
                            uploadDeviceReq.setAction("preMeetStart");
                            uploadDeviceReq.setContent(JSON.toJSONString(recordEntity));
                            log.info("preMeetStart send msg :{}", roomDeviceEntity.getDeviceCode());
                            messageFeign.downMsg(uploadDeviceReq);
                        }
                    }catch (Exception e){
                        log.error("设置异常",e);
                    }

                }

            }

            if (!ObjectUtils.isEmpty(basicSetEntity.getPostMeetStart()) && basicSetEntity.getPostMeetStart() > 0) {
                mettingRecordQuery = new MettingRecordQuery();
                mettingRecordQuery.setMeetStatus(MeetStatusEnum.进行中.getValue());
                List<MettingRecordEntity> pendRecordEntities = mettingRecordService.find(mettingRecordQuery);
                for (MettingRecordEntity pendRecordEntity : pendRecordEntities) {
                    long between = DateUtil.between(pendRecordEntity.getMeetTimeStart(), new Date(), DateUnit.MINUTE);
                    if (between >= basicSetEntity.getPostMeetStart()) {
                        //结束通知 通过redis 去重复
                        long sub = DateUtil.between(pendRecordEntity.getMeetTimeStart(), pendRecordEntity.getMeetTimeEnd(), DateUnit.SECOND, true);
                        boolean setnx = cacheService.setnx(RedisKey.KEY_METTING_END_CACHE, pendRecordEntity.getId(), sub);
                        if (setnx) {
                            RoomDeviceQuery roomDeviceQuery = new RoomDeviceQuery();
                            roomDeviceQuery.setRoomId(pendRecordEntity.getRoomId());
                            RoomDeviceEntity roomDeviceEntity = roomDeviceService.selectOne(roomDeviceQuery);
                            if (ObjectUtils.isEmpty(roomDeviceEntity)) return;

                            UploadDeviceReq uploadDeviceReq = new UploadDeviceReq();
                            uploadDeviceReq.setDeviceCodeList(Arrays.asList(roomDeviceEntity.getDeviceCode()));
                            uploadDeviceReq.setAction("postMeet");
                            Rest<String> rest = messageFeign.downMsg(uploadDeviceReq);
                            log.info("会议结束提前通知 postMeet 返回结果：{}", JSON.toJSONString(uploadDeviceReq));
                        }
                    }
                }
            }
        }
    }

    @Override
    public void stopTask(ITask task) throws AppException {

    }

    public static void main(String[] args) {


        long between = DateUtil.between(new Date(), DateUtil.offsetMinute(new Date(), 5), DateUnit.MINUTE);

        System.out.println(between);

    }

}
