package com.hotwj.platform.resourceManagement.govEnterpriseUnit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hotwj.platform.resourceManagement.govEnterpriseUnit.domain.HotGovEnterpriseUnit;
import com.hotwj.platform.resourceManagement.govEnterpriseUnit.domain.bo.HotGovEnterpriseUnitBo;
import com.hotwj.platform.resourceManagement.govEnterpriseUnit.domain.vo.HotGovEnterpriseUnitVo;
import com.hotwj.platform.resourceManagement.govEnterpriseUnit.mapper.HotGovEnterpriseUnitMapper;
import com.hotwj.platform.resourceManagement.govEnterpriseUnit.service.IHotGovEnterpriseUnitService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 政企单位Service业务层处理
 *
 * @author shihongwei
 * @date 2026-01-12
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class HotGovEnterpriseUnitServiceImpl implements IHotGovEnterpriseUnitService {

    private final HotGovEnterpriseUnitMapper baseMapper;

    /**
     * 查询政企单位
     *
     * @param id 主键
     * @return 政企单位
     */
    @Override
    public HotGovEnterpriseUnitVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询政企单位列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 政企单位分页列表
     */
    @Override
    public TableDataInfo<HotGovEnterpriseUnitVo> queryPageList(HotGovEnterpriseUnitBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<HotGovEnterpriseUnit> lqw = buildQueryWrapper(bo);
        Page<HotGovEnterpriseUnitVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        // 填充上级单位名称
        if (!result.getRecords().isEmpty()) {
            // 收集所有 parentUnitId
            java.util.Set<Long> parentIds = result.getRecords().stream()
                    .map(HotGovEnterpriseUnitVo::getParentUnitId)
                    .filter(id -> id != null && id != 0)
                    .collect(java.util.stream.Collectors.toSet());

            if (!parentIds.isEmpty()) {
                // 批量查询父级单位
                List<HotGovEnterpriseUnit> parents = baseMapper.selectBatchIds(parentIds);
                Map<Long, String> parentNameMap = parents.stream()
                        .collect(java.util.stream.Collectors.toMap(HotGovEnterpriseUnit::getId, HotGovEnterpriseUnit::getUnitName));

                // 设置 parentUnitName
                for (HotGovEnterpriseUnitVo vo : result.getRecords()) {
                    if (vo.getParentUnitId() != null && parentNameMap.containsKey(vo.getParentUnitId())) {
                        vo.setParentUnitName(parentNameMap.get(vo.getParentUnitId()));
                    }
                }
            }
        }

        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的政企单位列表
     *
     * @param bo 查询条件
     * @return 政企单位列表
     */
    @Override
    public List<HotGovEnterpriseUnitVo> queryList(HotGovEnterpriseUnitBo bo) {
        LambdaQueryWrapper<HotGovEnterpriseUnit> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询可选的上级单位列表（排除自身及子孙节点）
     *
     * @param id 当前单位ID
     * @param unitType 单位类型
     * @return 可选的上级单位列表
     */
    @Override
    public List<HotGovEnterpriseUnitVo> queryParentList(Long id, Long unitType) {
        // 查询所有单位
        LambdaQueryWrapper<HotGovEnterpriseUnit> wrapper = Wrappers.lambdaQuery();
        List<HotGovEnterpriseUnitVo> allUnits = baseMapper.selectVoList(wrapper);

        // 排除自身及子孙节点
        java.util.Set<Long> excludeIds = new java.util.HashSet<>();
        if (id != null) {
            excludeIds.add(id);
            findChildren(allUnits, id, excludeIds);
        }

        // 过滤
        return allUnits.stream()
                .filter(unit -> !excludeIds.contains(unit.getId()))
                .filter(unit -> unitType == null || unitType.equals(unit.getUnitType()))
                .collect(java.util.stream.Collectors.toList());
    }

    private void findChildren(List<HotGovEnterpriseUnitVo> allUnits, Long parentId, java.util.Set<Long> excludeIds) {
        for (HotGovEnterpriseUnitVo unit : allUnits) {
            if (parentId.equals(unit.getParentUnitId()) && !excludeIds.contains(unit.getId())) {
                excludeIds.add(unit.getId());
                findChildren(allUnits, unit.getId(), excludeIds);
            }
        }
    }

    private LambdaQueryWrapper<HotGovEnterpriseUnit> buildQueryWrapper(HotGovEnterpriseUnitBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HotGovEnterpriseUnit> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(HotGovEnterpriseUnit::getId);
        lqw.eq(bo.getUnitType() != null, HotGovEnterpriseUnit::getUnitType, bo.getUnitType());
        lqw.eq(bo.getParentUnitId() != null, HotGovEnterpriseUnit::getParentUnitId, bo.getParentUnitId());
        lqw.like(StringUtils.isNotBlank(bo.getUnitName()), HotGovEnterpriseUnit::getUnitName, bo.getUnitName());
        lqw.eq(StringUtils.isNotBlank(bo.getProvinceCode()), HotGovEnterpriseUnit::getProvinceCode, bo.getProvinceCode());
        lqw.eq(StringUtils.isNotBlank(bo.getCityCode()), HotGovEnterpriseUnit::getCityCode, bo.getCityCode());
        lqw.eq(StringUtils.isNotBlank(bo.getDistrictCode()), HotGovEnterpriseUnit::getDistrictCode, bo.getDistrictCode());
        lqw.like(StringUtils.isNotBlank(bo.getContactName()), HotGovEnterpriseUnit::getContactName, bo.getContactName());
        lqw.like(StringUtils.isNotBlank(bo.getContactPhone()), HotGovEnterpriseUnit::getContactPhone, bo.getContactPhone());
        lqw.like(StringUtils.isNotBlank(bo.getBackupContactName()), HotGovEnterpriseUnit::getBackupContactName, bo.getBackupContactName());
        lqw.like(StringUtils.isNotBlank(bo.getBackupContactPhone()), HotGovEnterpriseUnit::getBackupContactPhone, bo.getBackupContactPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getOfficeAddress()), HotGovEnterpriseUnit::getOfficeAddress, bo.getOfficeAddress());
        lqw.eq(bo.getIsDeleted() != null, HotGovEnterpriseUnit::getIsDeleted, bo.getIsDeleted());
        return lqw;
    }

    /**
     * 新增政企单位
     *
     * @param bo 政企单位
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(HotGovEnterpriseUnitBo bo) {
        HotGovEnterpriseUnit add = MapstructUtils.convert(bo, HotGovEnterpriseUnit.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改政企单位
     *
     * @param bo 政企单位
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(HotGovEnterpriseUnitBo bo) {
        HotGovEnterpriseUnit update = MapstructUtils.convert(bo, HotGovEnterpriseUnit.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HotGovEnterpriseUnit entity) {
        // 校验上级单位不能是自己
        if (entity.getParentUnitId() != null && entity.getId() != null && entity.getParentUnitId().equals(entity.getId())) {
            throw new ServiceException("上级单位不能是自己");
        }

        // 校验上级单位不能包含本单位，产生循环引用
        if (entity.getParentUnitId() != null) {
            checkRecursion(entity.getId(), entity.getParentUnitId());
        }
    }

    private void checkRecursion(Long currentId, Long parentId) {
        Long nextParentId = parentId;
        int depth = 0;
        while (nextParentId != null && nextParentId != 0L) {
            if (depth > 100) break; // 防止死循环

            if (currentId != null && nextParentId.equals(currentId)) {
                throw new ServiceException("上级单位不能包含本单位，产生循环引用");
            }

            HotGovEnterpriseUnit parent = baseMapper.selectById(nextParentId);
            if (parent == null) {
                break;
            }
            nextParentId = parent.getParentUnitId();
            depth++;
        }
    }

    /**
     * 校验并批量删除政企单位信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
