package com.zksy.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksy.base.domain.EquipmentBase;
import com.zksy.base.domain.EquipmentStatus;
import com.zksy.base.mapper.EquipmentBaseMapper;
import com.zksy.base.mapper.EquipmentStatusMapper;
import com.zksy.base.service.EquipmentStatusService;
import com.zksy.common.core.domain.entity.SysUser;
import com.zksy.common.exception.ServiceException;
import com.zksy.manhole.dto.in.EquipmentStatusInDTO;
import com.zksy.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMapper, EquipmentStatus>
        implements EquipmentStatusService {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private EquipmentBaseMapper equipmentBaseMapper;

    @Override
    public Page<EquipmentStatus> findByPage(long pageNum, long pageSize,
                                            String statusId,String equipmentId,
                                            Integer currentStatus,Integer alarmStatus,
                                            Integer onlineStatus,Long userId) {
        Page<EquipmentStatus> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<EquipmentStatus> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EquipmentStatus::getStatusId,statusId)
                    .eq(EquipmentStatus::getCurrentStatus,currentStatus)
                    .eq(EquipmentStatus::getAlarmStatus,alarmStatus)
                    .eq(EquipmentStatus::getOnlineStatus,onlineStatus)
                    .eq(EquipmentStatus::getUserId,userId);
        return this.page(page,queryWrapper);
    }

    /**
     * 新增仪器状态
     * @param entity
     * @return
     */
    @Override
    public boolean saveWithCheck(EquipmentStatus entity) {
        //校验关联的设备是否存在
        String equipmentId = entity.getEquipmentId();
        if (equipmentBaseMapper.selectById(equipmentId) == null) {
            throw new ServiceException("关联的设备不存在：" + equipmentId);
        }

        //校验设备是否已存在状态记录，如果存在则转为更新
        LambdaQueryWrapper<EquipmentStatus> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EquipmentStatus::getEquipmentId, equipmentId);
        EquipmentStatus existing = this.getOne(wrapper);
        if (existing != null) {
            entity.setStatusId(existing.getStatusId());
            return this.updateById(entity);
        }

        //校验当前状态值是否合法（1-在用,2-闲置,3-维修,4-报废,5-待入库）
        Integer currentStatus = entity.getCurrentStatus();
        if (currentStatus == null || currentStatus < 1 || currentStatus > 5) {
            throw new ServiceException("设备状态值无效，必须为1-5之间的整数：" + currentStatus);
        }

        //校验负责人ID
        Long userId = entity.getUserId();
        if (userId != null) {
            SysUser user = sysUserService.selectUserById(userId);
            if (user == null || "2".equals(user.getDelFlag())) { // 排除已删除的用户
                throw new ServiceException("负责人ID不存在或已删除：" + userId);
            }
        }
        //新增
        return this.save(entity);
    }

    /**
     * 批量新增仪器状态
     * @param entityList
     * @return
     */
    @Override
    @Transactional
    public boolean saveBatchWithCheck(List<EquipmentStatus> entityList) {
        //批量校验id
        List<String> equipmentIds = entityList.stream()
                .map(EquipmentStatus::getEquipmentId)
                .collect(Collectors.toList());

        Set<String> duplicateEqIds = new HashSet<>();
        Set<String> tempEqIds = new HashSet<>();
        for (String eqId : equipmentIds) {
            if (tempEqIds.contains(eqId)) {
                duplicateEqIds.add(eqId);
            } else {
                tempEqIds.add(eqId);
            }
        }
        if (!duplicateEqIds.isEmpty()) {
            throw new ServiceException("批量列表中存在重复设备ID：" + duplicateEqIds);
        }

        // 校验设备是否存在，外键
        List<String> existEqIds = equipmentBaseMapper.selectBatchIds(equipmentIds).stream()
                .map(EquipmentBase::getEquipmentId)
                .collect(Collectors.toList());
        Set<String> invalidEqIds = equipmentIds.stream()
                .filter(id -> !existEqIds.contains(id))
                .collect(Collectors.toSet());
        if (!invalidEqIds.isEmpty()) {
            throw new ServiceException("存在无效的设备ID：" + invalidEqIds);
        }

        // 校验这些设备是否已存在状态记录
        LambdaQueryWrapper<EquipmentStatus> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(EquipmentStatus::getEquipmentId, equipmentIds);
        List<String> alreadyExistEqIds = this.list(wrapper).stream()
                .map(EquipmentStatus::getEquipmentId)
                .collect(Collectors.toList());
        if (!alreadyExistEqIds.isEmpty()) {
            throw new ServiceException("以下设备已存在状态记录，不能重复新增：" + alreadyExistEqIds);
        }

        //校验
        for (EquipmentStatus entity : entityList) {
            //校验状态值范围是否合法
            Integer status = entity.getCurrentStatus();
            if (status == null || status < 1 || status > 5) {
                throw new ServiceException("设备状态值无效（必须为1-5）：" + status + "（状态记录ID：" + entity.getStatusId() + "）");
            }

            //校验负责人ID
            Long userId = entity.getUserId();
            if (userId != null) {
                SysUser user = sysUserService.selectUserById(userId);
                if (user == null || "2".equals(user.getDelFlag())) { // 检查用户是否存在且未被删除
                    throw new ServiceException("负责人不存在或已删除：" + userId + "（状态记录ID：" + entity.getStatusId() + "）");
                }
            }
        }
        //批量新增
        return this.saveBatch(entityList);
    }

    /**
     * 修改仪器状态
     * @param entity
     * @return
     */
    @Override
    public boolean updateWithCheck(EquipmentStatus entity) {
        //校验当前状态记录是否存在
        Integer statusId = entity.getStatusId();
        EquipmentStatus oldStatus = null;
        if (statusId != null) {
            oldStatus = this.getById(statusId);
        }
        // 如果没有statusId，尝试通过equipmentId查找
        if (oldStatus == null && entity.getEquipmentId() != null) {
            LambdaQueryWrapper<EquipmentStatus> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(EquipmentStatus::getEquipmentId, entity.getEquipmentId());
            oldStatus = this.getOne(wrapper);
            if (oldStatus != null) {
                entity.setStatusId(oldStatus.getStatusId());
            }
        }
        if (oldStatus == null) {
            throw new ServiceException("设备状态记录不存在：" + statusId);
        }

        //校验设备ID是否被篡改
        String newEqId = entity.getEquipmentId();
        String oldEqId = oldStatus.getEquipmentId();
        if (newEqId != null && !newEqId.equals(oldEqId)) {
            throw new ServiceException("不允许修改设备ID（如需更换设备，请删除旧记录后重新新增）");
        }

        //校验状态值合法性
        Integer status = entity.getCurrentStatus();
        if (status != null && (status < 1 || status > 5)) {
            throw new ServiceException("设备状态值无效（必须为1-5）：" + status);
        }

        // 校验负责人ID
        Long newUserId = entity.getUserId();
        if (newUserId != null) {
            SysUser user = sysUserService.selectUserById(newUserId);
            if (user == null || "2".equals(user.getDelFlag())) {
                throw new ServiceException("负责人不存在或已删除：" + newUserId);
            }
        }
        //更新
        return this.updateById(entity);
    }

    /**
     * 修改设备状态
     * @param inDTO
     * @return
     */
    @Override
    public boolean updateDeviceStatus(EquipmentStatusInDTO inDTO) {
        log.info("修改设备状态-入参:{}", inDTO);
        //校验状态值合法性
        Integer status = inDTO.getCurrentStatus();
        if (status != null && (status < 1 || status > 5)) {
            throw new ServiceException("设备状态值无效（必须为1-5）：" + status);
        }
        //校验当前状态记录是否存在
        boolean update = this.lambdaUpdate()
                .set(EquipmentStatus::getCurrentStatus, inDTO.getCurrentStatus())
                .set(EquipmentStatus::getStatusUpdateTime, new Date())
                .eq(EquipmentStatus::getEquipmentId, inDTO.getEquipmentId())
                .update();
        return update;
    }

    /**
     * 根据设备编码（deviceCode）查询设备状态
     * <p>
     * 先通过 equipment_base 表找到 equipmentId，再查询 equipment_status 表。
     *
     * @param deviceCode 设备编码
     * @return 设备状态，未找到返回 null
     */
    @Override
    public EquipmentStatus getByDeviceCode(String deviceCode) {
        LambdaQueryWrapper<EquipmentBase> baseWrapper = new LambdaQueryWrapper<>();
        baseWrapper.eq(EquipmentBase::getEquipmentCode, deviceCode);
        EquipmentBase equipmentBase = equipmentBaseMapper.selectOne(baseWrapper);

        if (equipmentBase == null) {
            log.warn("未找到设备: deviceCode={}", deviceCode);
            return null;
        }

        LambdaQueryWrapper<EquipmentStatus> statusWrapper = new LambdaQueryWrapper<>();
        statusWrapper.eq(EquipmentStatus::getEquipmentId, equipmentBase.getEquipmentId());
        EquipmentStatus status = this.getOne(statusWrapper);

        log.info("根据设备编码查询状态: deviceCode={}, equipmentId={}, found={}",
                deviceCode, equipmentBase.getEquipmentId(), status != null);
        return status;
    }
}
