package com.usky.ems.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.usky.common.core.exception.BusinessException;
import com.usky.ems.domain.BaseSpace;
import com.usky.ems.domain.BaseSpaceGateway;
import com.usky.ems.domain.DmpGateway;
import com.usky.ems.domain.EmsDevice;
import com.usky.ems.domain.EmsDeviceEvent;
import com.usky.ems.mapper.BaseSpaceGatewayMapper;
import com.usky.ems.mapper.DmpGatewayMapper;
import com.usky.ems.mapper.EmsDeviceEventMapper;
import com.usky.ems.mapper.EmsDeviceMapper;
import com.usky.ems.service.BaseSpaceService;
import com.usky.ems.service.EmsDeviceEventService;
import com.usky.ems.service.vo.DeviceEventDTO;
import com.usky.ems.service.vo.DeviceEventVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 设备事件服务实现（全部逻辑在 Service 层）
 */
@Service
public class EmsDeviceEventServiceImpl implements EmsDeviceEventService {

    @Autowired
    private BaseSpaceService baseSpaceService;

    @Autowired
    private EmsDeviceMapper emsDeviceMapper;

    @Autowired
    private BaseSpaceGatewayMapper baseSpaceGatewayMapper;

    @Autowired
    private DmpGatewayMapper dmpGatewayMapper;

    @Autowired
    private EmsDeviceEventMapper emsDeviceEventMapper;

    @Override
    public List<DeviceEventVO> list(DeviceEventDTO dto) {
        if (dto == null || dto.getInstallationLocation() == null) {
            throw new BusinessException("安装位置不存在");
        }

        BaseSpace space = baseSpaceService.getById(dto.getInstallationLocation());
        if (space == null) {
            throw new BusinessException("安装位置不存在");
        }

        // 1) 递归获取所有子空间 + 本空间
        List<BaseSpace> spaceList = new ArrayList<>(baseSpaceService.recursiveAllChildrenNode(dto.getInstallationLocation()));
        spaceList.add(space);

        List<Long> spaceIds = spaceList.stream()
                .map(BaseSpace::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        Map<Long, String> spaceMap = spaceList.stream()
                .filter(s -> s.getId() != null)
                .collect(Collectors.toMap(BaseSpace::getId, BaseSpace::getName, (a, b) -> a));

        // 2) 根据 deviceType 取设备/网关列表及其名称、空间映射
        Integer deviceType = dto.getDeviceType();
        if (deviceType == null || (deviceType != 1 && deviceType != 2)) {
            throw new BusinessException("设备类型错误");
        }

        List<String> ids;
        Map<String, String> nameMap;
        Map<String, Long> spaceIdMap;

        if (deviceType == 1) {
            List<EmsDevice> devices = emsDeviceMapper.selectList(new LambdaQueryWrapper<EmsDevice>()
                    .in(EmsDevice::getInstallationLocation, spaceIds));
            if (devices == null || devices.isEmpty()) {
                return Collections.emptyList();
            }
            ids = devices.stream().map(EmsDevice::getId).filter(Objects::nonNull).collect(Collectors.toList());
            nameMap = devices.stream().filter(d -> d.getId() != null)
                    .collect(Collectors.toMap(EmsDevice::getId, EmsDevice::getName, (a, b) -> a));
            spaceIdMap = devices.stream().filter(d -> d.getId() != null)
                    .collect(Collectors.toMap(EmsDevice::getId, EmsDevice::getInstallationLocation, (a, b) -> a));
        } else {
            List<BaseSpaceGateway> links = baseSpaceGatewayMapper.selectList(
                    new LambdaQueryWrapper<BaseSpaceGateway>().in(BaseSpaceGateway::getSpaceId, spaceIds));
            if (links == null || links.isEmpty()) {
                return Collections.emptyList();
            }
            java.util.Map<String, Long> uuidToSpace = new java.util.HashMap<>();
            for (BaseSpaceGateway link : links) {
                if (link.getGatewayUuid() != null && link.getSpaceId() != null) {
                    uuidToSpace.putIfAbsent(link.getGatewayUuid(), link.getSpaceId());
                }
            }
            if (uuidToSpace.isEmpty()) {
                return Collections.emptyList();
            }
            List<DmpGateway> gateways = dmpGatewayMapper.selectList(
                    new LambdaQueryWrapper<DmpGateway>().in(DmpGateway::getDeviceUuid, uuidToSpace.keySet()));
            if (gateways == null || gateways.isEmpty()) {
                return Collections.emptyList();
            }
            ids = gateways.stream().map(DmpGateway::getDeviceUuid).filter(Objects::nonNull).collect(Collectors.toList());
            nameMap = gateways.stream().filter(g -> g.getDeviceUuid() != null)
                    .collect(Collectors.toMap(DmpGateway::getDeviceUuid, DmpGateway::getName, (a, b) -> a));
            spaceIdMap = gateways.stream().filter(g -> g.getDeviceUuid() != null)
                    .collect(Collectors.toMap(DmpGateway::getDeviceUuid, g -> uuidToSpace.get(g.getDeviceUuid()), (a, b) -> a));
        }

        if (ids.isEmpty()) {
            return Collections.emptyList();
        }

        // 3) 查事件表 ems_device_event
        LambdaQueryWrapper<EmsDeviceEvent> eventWrapper = new LambdaQueryWrapper<>();
        eventWrapper.eq(EmsDeviceEvent::getDeviceType, deviceType)
                .in(EmsDeviceEvent::getDeviceId, ids);

        if (dto.getStartTime() != null && dto.getEndTime() != null) {
            eventWrapper.between(EmsDeviceEvent::getStartTime, dto.getStartTime(), dto.getEndTime());
        } else if (dto.getStartTime() != null) {
            eventWrapper.ge(EmsDeviceEvent::getStartTime, dto.getStartTime());
        } else if (dto.getEndTime() != null) {
            eventWrapper.le(EmsDeviceEvent::getStartTime, dto.getEndTime());
        }

        List<EmsDeviceEvent> eventList = emsDeviceEventMapper.selectList(eventWrapper);
        if (eventList == null || eventList.isEmpty()) {
            return Collections.emptyList();
        }

        LocalDateTime now = LocalDateTime.now();
        List<DeviceEventVO> result = new ArrayList<>(eventList.size());
        for (EmsDeviceEvent deviceEvent : eventList) {
            DeviceEventVO vo = new DeviceEventVO();
            vo.setDeviceId(deviceEvent.getDeviceId());
            vo.setDeviceName(nameMap.get(deviceEvent.getDeviceId()));
            vo.setContent(deviceEvent.getContent());
            Long sid = spaceIdMap.get(deviceEvent.getDeviceId());
            vo.setInstallationLocation(sid == null ? null : spaceMap.get(sid));
            vo.setEventType(deviceEvent.getEventType());
            vo.setStartTime(deviceEvent.getStartTime());
            vo.setIdentifier(deviceEvent.getIdentifier());
            vo.setDuration(formatDuration(deviceEvent.getStartTime(), now));
            result.add(vo);
        }

        result.sort(Comparator.comparing(DeviceEventVO::getDeviceName,
                Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER)));

        return result;
    }

    private String formatDuration(LocalDateTime start, LocalDateTime end) {
        if (start == null || end == null) {
            return null;
        }
        Duration duration = Duration.between(start, end);
        long minutes = duration.toMinutes();
        if (minutes < 0) {
            minutes = 0;
        }
        if (minutes >= 1440L) {
            long days = minutes / 1440L;
            long hours = (minutes % 1440L) / 60L;
            long mins = minutes % 60L;
            return days + "天" + hours + "小时" + mins + "分钟";
        }
        if (minutes >= 60L) {
            long hours = minutes / 60L;
            long mins = minutes % 60L;
            return hours + "小时" + mins + "分钟";
        }
        return minutes + "分钟";
    }
}

