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

import com.mortals.framework.model.PageInfo;
import com.mortals.xhx.common.pdu.UploadDeviceReq;
import com.mortals.xhx.feign.device.IDeviceMessageFeign;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceQuery;
import com.mortals.xhx.module.device.service.DeviceService;
import com.mortals.xhx.module.notice.model.NoticeEntity;
import com.mortals.xhx.module.notice.model.NoticeQuery;
import com.mortals.xhx.module.notice.model.NoticeRoomEntity;
import com.mortals.xhx.module.notice.model.NoticeRoomQuery;
import com.mortals.xhx.module.notice.service.NoticeRoomService;
import com.mortals.xhx.module.notice.service.NoticeService;
import com.mortals.xhx.module.workman.model.WorkmanQuery;
import com.mortals.xhx.module.workman.service.WorkmanService;
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.room.dao.RoomDao;
import com.mortals.xhx.module.room.model.RoomEntity;
import com.mortals.xhx.module.room.service.RoomService;
import org.springframework.beans.factory.annotation.Autowired;
import com.mortals.xhx.module.room.model.RoomDeviceEntity;
import com.mortals.xhx.module.room.model.RoomDeviceQuery;
import com.mortals.xhx.module.room.service.RoomDeviceService;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

/**
 * RoomService
 * 房间管理 service实现
 *
 * @author zxfei
 * @date 2023-05-29
 */
@Service("roomService")
@Slf4j
public class RoomServiceImpl extends AbstractCRUDServiceImpl<RoomDao, RoomEntity, Long> implements RoomService {
    @Autowired
    private RoomDeviceService roomDeviceService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private WorkmanService workmanService;
    @Autowired
    private NoticeRoomService noticeRoomService;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private IDeviceMessageFeign messageFeign;


    @Override
    protected void findAfter(RoomEntity params, PageInfo pageInfo, Context context, List<RoomEntity> list) throws AppException {
        super.findAfter(params, pageInfo, context, list);
        Map<Long, Long> collect = workmanService.find(new WorkmanQuery()).stream().collect(Collectors.groupingBy(x -> x.getRoomId(), Collectors.counting()));
        list.forEach(item -> {
            item.setNoticeList(new ArrayList<>());
            List<NoticeRoomEntity> noticeRoomEntities = noticeRoomService.find(new NoticeRoomQuery().roomId(item.getId()));
            if (!ObjectUtils.isEmpty(noticeRoomEntities)) {
                NoticeQuery noticeQuery = new NoticeQuery();
                noticeQuery.setIdList(noticeRoomEntities.stream().map(i -> i.getNoticeId()).collect(Collectors.toList()));
                List<NoticeEntity> noticeEntities = noticeService.find(noticeQuery, context);
                if (!ObjectUtils.isEmpty(noticeEntities)) {
                    item.setNoticeList(noticeEntities);
                }
            }
            item.setCountPerson(collect.getOrDefault(item.getId(), item.getCountPerson()));
        });
    }

    @Override
    protected void saveAfter(RoomEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getRoomDeviceList())) {

            entity.getRoomDeviceList().stream().peek(item -> {
                item.setRoomId(entity.getId());
                item.setRoomName(entity.getRoomName());
                DeviceEntity deviceCache = deviceService.getCache(item.getDeviceId().toString());
                item.setDeviceId(item.getDeviceId());
                item.setDeviceCode(deviceCache == null ? "" : deviceCache.getDeviceCode());
                item.setDeviceName(deviceCache == null ? "" : deviceCache.getDeviceName());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());

                DeviceEntity deviceEntity = new DeviceEntity();
                deviceEntity.setId(item.getDeviceId());
                deviceEntity.setRoomId(entity.getId());
                deviceEntity.setRoomName(entity.getRoomName());
                deviceService.update(deviceEntity);
            }).count();
            roomDeviceService.save(entity.getRoomDeviceList());
        }

        if (!ObjectUtils.isEmpty(entity.getNoticeId())) {
            //查询notice
            NoticeEntity noticeEntity = noticeService.get(entity.getNoticeId(), context);
            if (!ObjectUtils.isEmpty(noticeEntity)) {

                NoticeRoomEntity noticeRoomEntity = new NoticeRoomEntity();
                noticeRoomEntity.initAttrValue();
                noticeRoomEntity.setRoomId(entity.getId());
                noticeRoomEntity.setRoomName(entity.getRoomName());
                noticeRoomEntity.setNoticeId(noticeEntity.getId());
                noticeRoomEntity.setCreateTime(new Date());
                noticeRoomEntity.setCreateUserId(this.getContextUserId(context));
                noticeRoomService.save(noticeRoomEntity, context);
            }
        }

        UploadDeviceReq uploadDeviceReq = new UploadDeviceReq();
        uploadDeviceReq.setDeviceCodeList( roomDeviceService.find(new RoomDeviceQuery().roomId(entity.getId())).stream().map(i->i.getDeviceCode()).collect(Collectors.toList()));
        uploadDeviceReq.setAction("refreshMetting");
        messageFeign.downMsg(uploadDeviceReq);

        super.saveAfter(entity, context);
    }

    @Override
    protected void updateAfter(RoomEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getRoomDeviceList())) {

            List<Long> deviceIdList = entity.getRoomDeviceList().stream().map(i -> i.getDeviceId()).collect(Collectors.toList());
            RoomDeviceQuery roomDeviceQuery = new RoomDeviceQuery();
            roomDeviceQuery.setDeviceIdList(deviceIdList);

            Long[] roomDeviceIds = roomDeviceService.find(roomDeviceQuery).stream().map(RoomDeviceEntity::getId).toArray(Long[]::new);
            roomDeviceService.remove(roomDeviceIds, context);

            roomDeviceIds = roomDeviceService.find(new RoomDeviceQuery().roomId(entity.getId())).stream().map(RoomDeviceEntity::getId).toArray(Long[]::new);
            roomDeviceService.remove(roomDeviceIds, context);
            entity.getRoomDeviceList().stream().peek(item -> {
                item.setRoomId(entity.getId());
                item.setRoomName(entity.getRoomName());
                DeviceEntity deviceCache = deviceService.getCache(item.getDeviceId().toString());
                item.setDeviceId(item.getDeviceId());
                item.setDeviceCode(deviceCache == null ? "" : deviceCache.getDeviceCode());
                item.setDeviceName(deviceCache == null ? "" : deviceCache.getDeviceName());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
                item.setUpdateUserId(this.getContextUserId(context));
                item.setUpdateTime(new Date());

                DeviceEntity deviceEntity = new DeviceEntity();
                deviceEntity.setId(item.getDeviceId());
                deviceEntity.setRoomId(entity.getId());
                deviceEntity.setRoomName(entity.getRoomName());
                deviceService.update(deviceEntity);

            }).count();
            roomDeviceService.save(entity.getRoomDeviceList());
        }

        if (!ObjectUtils.isEmpty(entity.getNoticeId())) {
            //查询notice
            NoticeEntity noticeEntity = noticeService.get(entity.getNoticeId(), context);
            if (!ObjectUtils.isEmpty(noticeEntity)) {

                NoticeRoomQuery noticeRoomQuery = new NoticeRoomQuery();
                noticeRoomQuery.setRoomId(entity.getId());

                NoticeRoomEntity temp = noticeRoomService.selectOne(noticeRoomQuery);

                if (!ObjectUtils.isEmpty(temp)) {

                    if (temp.getId() != entity.getNoticeId()) {
                        //删除后新增
                        noticeRoomService.remove(temp.getId(), context);

                        NoticeRoomEntity noticeRoomEntity = new NoticeRoomEntity();
                        noticeRoomEntity.initAttrValue();
                        noticeRoomEntity.setRoomId(entity.getId());
                        noticeRoomEntity.setRoomName(entity.getRoomName());
                        noticeRoomEntity.setNoticeId(noticeEntity.getId());
                        noticeRoomEntity.setCreateTime(new Date());
                        noticeRoomEntity.setCreateUserId(this.getContextUserId(context));
                        noticeRoomService.save(noticeRoomEntity, context);
                    }
                } else {
                    NoticeRoomEntity noticeRoomEntity = new NoticeRoomEntity();
                    noticeRoomEntity.initAttrValue();
                    noticeRoomEntity.setRoomId(entity.getId());
                    noticeRoomEntity.setRoomName(entity.getRoomName());
                    noticeRoomEntity.setNoticeId(noticeEntity.getId());
                    noticeRoomEntity.setCreateTime(new Date());
                    noticeRoomEntity.setCreateUserId(this.getContextUserId(context));
                    noticeRoomService.save(noticeRoomEntity, context);
                }
            }
        }
        UploadDeviceReq uploadDeviceReq = new UploadDeviceReq();
        uploadDeviceReq.setDeviceCodeList( roomDeviceService.find(new RoomDeviceQuery().roomId(entity.getId())).stream().map(i->i.getDeviceCode()).collect(Collectors.toList()));
        uploadDeviceReq.setAction("refreshWorkman");
        messageFeign.downMsg(uploadDeviceReq);
    }

    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        List<RoomDeviceEntity> roomDevicelist = roomDeviceService.find(new RoomDeviceQuery().roomIdList(Arrays.asList(ids)));
        roomDeviceService.removeList(roomDevicelist, context);

        roomDevicelist.stream().forEach(item -> {
            DeviceEntity deviceEntity = new DeviceEntity();
            deviceEntity.setId(item.getDeviceId());
            deviceEntity.setRoomId(-1L);
            deviceEntity.setRoomName("");
            deviceService.update(deviceEntity);
        });
        super.removeAfter(ids, context, result);
    }
}