package com.mortals.xhx.module.metting.service.impl;

import cn.hutool.core.date.*;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.common.code.MeetStatusEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.pdu.UploadDeviceReq;
import com.mortals.xhx.common.utils.SendNotifyTask;
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.MettingRecordQuery;
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.mortals.xhx.module.room.service.RoomService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.metting.dao.MettingRecordDao;
import com.mortals.xhx.module.metting.model.MettingRecordEntity;
import com.mortals.xhx.module.metting.service.MettingRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * MettingRecordService
 * 会议记录 service实现
 *
 * @author zxfei
 * @date 2023-05-22
 */
@Service("mettingRecordService")
@Slf4j
public class MettingRecordServiceImpl extends AbstractCRUDServiceImpl<MettingRecordDao, MettingRecordEntity, Long> implements MettingRecordService {

    @Autowired
    private IDeviceMessageFeign messageFeign;
    @Autowired
    private RoomService roomService;
    @Autowired
    private RoomDeviceService roomDeviceService;
    @Autowired
    private BasicSetService basicSetService;
/*
    @Override
    protected void validData(MettingRecordEntity entity, Context context) throws AppException {
        super.validData(entity, context);
        Date meetTimeStart = entity.getMeetTimeStart();
        Date meetTimeEnd = entity.getMeetTimeEnd();
        if (!ObjectUtils.isEmpty(meetTimeStart) && !ObjectUtils.isEmpty(meetTimeEnd)) {
            //开始时间不能大于结束时间
            int compare = DateUtil.compare(meetTimeStart, meetTimeEnd);
            if (compare > 0) {
                throw new AppException("会议开始时间不能大于结束时间！");
            }

            Boolean bool = checkExistStartMeetTime(entity);
            if (bool) {
                throw new AppException("当前会议室该时段已经存在等待或进行中的会议，请选择其它时间段！");
            }
        }
        UploadDeviceReq uploadDeviceReq = new UploadDeviceReq();
        RoomEntity roomEntity = roomService.get(entity.getRoomId(), context);
        if (!ObjectUtils.isEmpty(roomEntity)) {
            uploadDeviceReq.setDeviceCodeList(roomDeviceService.find(new RoomDeviceQuery().roomId(roomEntity.getId())).stream().map(i -> i.getDeviceCode()).collect(Collectors.toList()));
            uploadDeviceReq.setAction("refreshMetting");
            messageFeign.downMsg(uploadDeviceReq);
        }
    }*/




   /* @Override
    protected void findAfter(MettingRecordEntity params, PageInfo pageInfo, Context context, List<MettingRecordEntity> list) throws AppException {
        BasicSetEntity basicSetEntity = basicSetService.selectOne(new BasicSetEntity());
        if (!ObjectUtils.isEmpty(basicSetEntity) && !ObjectUtils.isEmpty(basicSetEntity.getPreMeetStart()) && basicSetEntity.getPreMeetStart() > 0) {
            //会议开始前几分钟 通知设备进行数据更新
            MettingRecordQuery mettingRecordQuery = new MettingRecordQuery();
            //mettingRecordQuery.setFinishMethod(FinishMethodEnum.自动结束.getValue());
            mettingRecordQuery.setMeetStatus(MeetStatusEnum.等待中.getValue());
            List<MettingRecordEntity> recordEntities = this.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)) {
                        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);
                    }
                }
            }
        }
        super.findAfter(params, pageInfo, context, list);
    }*/


    @Override
    protected void saveBefore(MettingRecordEntity entity, Context context) throws AppException {
        super.saveBefore(entity, context);
        checkStartAndEndTime(entity);
        Boolean bool = checkExistStartMeetTime(entity);
        if (bool) {
            throw new AppException("当前会议室该时段已经存在等待或进行中的会议，请选择其它时间段！");
        }

        int compare = DateUtil.compare(new Date(), entity.getMeetTimeEnd());
        if (compare > 0) {
            entity.setMeetStatus(MeetStatusEnum.已结束.getValue());
        }

        //判断 当前时间是否在开始与结束之间
        boolean in = DateUtil.isIn(new Date(), entity.getMeetTimeStart(), entity.getMeetTimeEnd());
        if (in) {
            entity.setMeetStatus(MeetStatusEnum.进行中.getValue());
        }
        //发送推送通知
        RoomDeviceQuery roomDeviceQuery = new RoomDeviceQuery();
        roomDeviceQuery.setRoomId(entity.getRoomId());
        RoomDeviceEntity roomDeviceEntity = roomDeviceService.selectOne(roomDeviceQuery);
        if (!ObjectUtils.isEmpty(roomDeviceEntity)) {
            UploadDeviceReq uploadDeviceReq = new UploadDeviceReq();
            uploadDeviceReq.setDeviceCodeList(Arrays.asList(roomDeviceEntity.getDeviceCode()));
            uploadDeviceReq.setAction("refreshMetting");
            log.info("refreshMetting send deviceList :{}", JSON.toJSONString(Arrays.asList(roomDeviceEntity.getDeviceCode())));
            messageFeign.downMsg(uploadDeviceReq);
        }
    }


    @Override
    protected void updateBefore(MettingRecordEntity entity, Context context) throws AppException {
        super.updateBefore(entity, context);

        //判断是否是手动结束会议
        MettingRecordEntity mettingRecordEntity = this.get(entity.getId());
        if (mettingRecordEntity.getMeetStatus() == MeetStatusEnum.进行中.getValue() && entity.getMeetStatus() == MeetStatusEnum.已结束.getValue()) {
            SendNotifyTask sendNotifyTask = new SendNotifyTask(mettingRecordEntity);
            ThreadPool.getInstance().execute(sendNotifyTask);
/*            //手动结束会议 延迟发送刷新通知
            UploadDeviceReq uploadDeviceReq = new UploadDeviceReq();
            RoomEntity roomEntity = roomService.get(mettingRecordEntity.getRoomId(), context);
            if (!ObjectUtils.isEmpty(roomEntity)) {
                List<String> deviceList = roomDeviceService.find(new RoomDeviceQuery().roomId(roomEntity.getId())).stream().map(i -> i.getDeviceCode()).collect(Collectors.toList());
                uploadDeviceReq.setDeviceCodeList(deviceList);
                uploadDeviceReq.setAction("postMeet");
                Rest<String> rest = messageFeign.downMsg(uploadDeviceReq);
                log.info("手动结束会议记录后发送消息：{}", JSON.toJSONString(deviceList));
            }*/
        }else{
            checkStartAndEndTime(entity);
            Boolean bool = checkExistStartMeetTime(entity);
            if (bool) {
                throw new AppException("当前会议室该时段已经存在等待或进行中的会议，请选择其它时间段！");
            }
        }
    }

    @Override
    protected void updateAfter(MettingRecordEntity entity, Context context) throws AppException {
        super.updateAfter(entity, context);
    }

    @Override
    public int remove(Long[] ids, Context context) throws AppException {
        this.removeBefore(ids, context);

        MettingRecordQuery mettingRecordQuery = new MettingRecordQuery();
        mettingRecordQuery.setIdList(Arrays.asList(ids));
        List<MettingRecordEntity> mettingRecordEntities = this.find(mettingRecordQuery);
        log.info("删除会议记录：{}", mettingRecordEntities.size());
        mettingRecordEntities.forEach(entity -> {
            if (entity.getMeetStatus() == MeetStatusEnum.进行中.getValue()) {
                throw new AppException(String.format("%s会议进行中，无法删除!", entity.getMeetName()));
            }
            UploadDeviceReq uploadDeviceReq = new UploadDeviceReq();
            RoomEntity roomEntity = roomService.get(entity.getRoomId(), context);
            if (!ObjectUtils.isEmpty(roomEntity)) {
                List<String> deviceList = roomDeviceService.find(new RoomDeviceQuery().roomId(roomEntity.getId())).stream().map(i -> i.getDeviceCode()).collect(Collectors.toList());
                uploadDeviceReq.setDeviceCodeList(deviceList);
                uploadDeviceReq.setAction("refreshMetting");
                Rest<String> rest = messageFeign.downMsg(uploadDeviceReq);
                log.info("删除会议记录后发送消息 deviceCode：{}", JSON.toJSONString(deviceList));

            }
        });

        int iRet = this.dao.delete(ids);
        this.removeAfter(ids, context, iRet);
        return iRet;
    }

    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        super.removeAfter(ids, context, result);
    }

    /**
     * 检测会议开始与结束时间
     *
     * @param entity
     */
    private void checkStartAndEndTime(MettingRecordEntity entity) {
        Date meetTimeStart = entity.getMeetTimeStart();
        Date meetTimeEnd = entity.getMeetTimeEnd();
        if (!ObjectUtils.isEmpty(meetTimeStart) && !ObjectUtils.isEmpty(meetTimeEnd)) {
            //开始时间不能大于结束时间
            int compare = DateUtil.compare(meetTimeStart, meetTimeEnd);
            if (compare > 0) {
                throw new AppException("会议开始时间不能大于结束时间！");
            }
        }
    }

    private Boolean checkExistStartMeetTime(MettingRecordEntity entity) {
        boolean bool = false;

        Date meetTimeStart = entity.getMeetTimeStart();
        Date meetTimeEnd = entity.getMeetTimeEnd();
        MettingRecordQuery mettingRecordQuery = new MettingRecordQuery();
        //mettingRecordQuery.setMeetStatus(MeetStatusEnum.等待中.getValue());
        mettingRecordQuery.setMeetStatusList(Arrays.asList(MeetStatusEnum.等待中.getValue(), MeetStatusEnum.进行中.getValue()));
        mettingRecordQuery.setRoomId(entity.getRoomId());
        //查询当前日期是否存在会议室占用
        mettingRecordQuery.setMeetDate(entity.getMeetDate());
        //判断选定的时间段 是否已经存在 时间段 求交集
        List<MettingRecordEntity> list = this.find(mettingRecordQuery);
        //校验当前时间段中是否已经存在未开始的会议
        if (!entity.newEntity()) {
            //更新时间段判断 排除已经存在的
            list = list.stream().filter(f -> f.getId() != entity.getId()).collect(Collectors.toList());
        }
        if (!ObjectUtils.isEmpty(list)) {
            //校验时间段是否有重合

            for (MettingRecordEntity mettingRecord : list) {
                //格式化分钟
                Date meetTimeStart1 = DateUtil.parseDateTime(DateUtil.format(mettingRecord.getMeetTimeStart(), "yyyy-MM-dd HH:mm") + ":00");
                Date meetTimeEnd1 = DateUtil.parseDateTime(DateUtil.format(mettingRecord.getMeetTimeEnd(), "yyyy-MM-dd HH:mm") + ":00");
                boolean in = belongCalendar(meetTimeStart, meetTimeStart1, meetTimeEnd1);
                boolean in1 = belongCalendar(meetTimeEnd, meetTimeStart1, meetTimeEnd1);
                if (in || in1) {
                    bool = true;
                    log.info("meetTimeStart:{},meetTimeEnd:{}, meetTimeStart1:{}, meetTimeEnd1:{}",
                            DateUtil.date(meetTimeStart).toTimeStr(), DateUtil.date(meetTimeEnd).toTimeStr(),
                            DateUtil.date(meetTimeStart1).toTimeStr(), DateUtil.date(meetTimeEnd1).toTimeStr());
                    break;
                }
            }

        }
        return bool;
    }

    public boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    public static void main(String[] args) {

        //meetTimeStart:09:30:00,meetTimeEnd:10:00:00, meetTimeStart1:09:21:00, meetTimeEnd1:09:30:00

        DateTime meetTimeStart = DateUtil.parseTime("09:30:59");
        DateTime meetTimeEnd = DateUtil.parseTime("09:22:00");
        DateTime meetTimeStart1 = DateUtil.parseTime("09:21:00");
        DateTime meetTimeEnd1 = DateUtil.parseTime("09:30:00");


/*        boolean in = MettingRecordServiceImpl.belongCalendar(meetTimeStart, meetTimeStart1, meetTimeEnd1);
        System.out.println(in);

        boolean in1 = DateUtil.isIn(meetTimeEnd, meetTimeStart1, meetTimeEnd1);

        System.out.println(in1);*/

/*        boolean in = DateUtil.isIn(meetTimeStart, meetTimeStart1, meetTimeEnd1);
        boolean in1 = DateUtil.isIn(meetTimeEnd, meetTimeStart1, meetTimeEnd1);

        System.out.println(in);

        System.out.println(in1);*/

    }
}