package com.zksy.drainage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksy.common.exception.ServiceException;
import com.zksy.drainage.domain.DrainagePartition;
import com.zksy.drainage.mapper.DrainagePartitionMapper;
import com.zksy.drainage.service.DrainagePartitionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 排水分区基础数据 ServiceImpl
 */
@Slf4j
@Service
public class DrainagePartitionServiceImpl extends ServiceImpl<DrainagePartitionMapper, DrainagePartition>
        implements DrainagePartitionService {

    @Override
    public Page<DrainagePartition> findByPage(long pageNum, long pageSize,
                                              String name, String district, String partitionType) {
        Page<DrainagePartition> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<DrainagePartition> wrapper = new LambdaQueryWrapper<>();
        if (name != null && !name.isEmpty()) {
            wrapper.like(DrainagePartition::getName, name);
        }
        if (district != null && !district.isEmpty()) {
            wrapper.like(DrainagePartition::getDistrict, district);
        }
        if (partitionType != null && !partitionType.isEmpty()) {
            wrapper.eq(DrainagePartition::getPartitionType, partitionType);
        }
        wrapper.orderByDesc(DrainagePartition::getCreateTime);
        return this.page(page, wrapper);
    }

    @Override
    @Transactional
    public boolean saveWithCheck(DrainagePartition entity) {
        LambdaQueryWrapper<DrainagePartition> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DrainagePartition::getName, entity.getName());
        if (this.count(wrapper) > 0) {
            throw new ServiceException("监测点名称已存在：" + entity.getName());
        }
        return this.save(entity);
    }

    @Override
    @Transactional
    public boolean updateWithCheck(DrainagePartition entity) {
        String id = entity.getId();
        if (this.getById(id) == null) {
            throw new ServiceException("排水分区不存在，无法修改：" + id);
        }
        String newName = entity.getName();
        if (newName != null && !newName.isEmpty()) {
            LambdaQueryWrapper<DrainagePartition> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DrainagePartition::getName, newName)
                    .ne(DrainagePartition::getId, id);
            if (this.count(wrapper) > 0) {
                throw new ServiceException("监测点名称已被使用：" + newName);
            }
        }
        return this.updateById(entity);
    }

    @Override
    @Transactional
    public boolean removeWithCheck(String id) {
        if (this.getById(id) == null) {
            throw new ServiceException("排水分区不存在：" + id);
        }
        return this.baseMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional
    public boolean removeBatchWithCheck(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new ServiceException("批量删除失败：ID列表不能为空");
        }
        List<DrainagePartition> existing = this.listByIds(ids);
        if (existing.isEmpty()) {
            throw new ServiceException("批量删除失败：所有ID均不存在");
        }
        List<String> existIds = existing.stream()
                .map(DrainagePartition::getId)
                .collect(Collectors.toList());
        List<String> invalidIds = ids.stream()
                .filter(id -> !existIds.contains(id))
                .collect(Collectors.toList());
        if (!invalidIds.isEmpty()) {
            log.warn("批量删除中存在无效排水分区ID：{}", invalidIds);
        }
        return this.removeByIds(existIds);
    }

    @Override
    public boolean bindEquipment(String partitionId, List<String> equipmentIds) {
        DrainagePartition partition = this.getById(partitionId);
        if (partition == null) return false;
        partition.setEquipmentId(String.join(",", equipmentIds));
        return this.updateById(partition);
    }
}
