package com.ruoyi.ems.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.ruoyi.ems.domain.Area;
import com.ruoyi.ems.domain.AreaBuilding;
import com.ruoyi.ems.domain.AreaBuildingZoning;
import com.ruoyi.ems.domain.common.AreaTier;
import com.ruoyi.ems.domain.vo.TreeEntity;
import com.ruoyi.ems.mapper.AreaMapper;
import com.ruoyi.ems.service.IAreaBuildingService;
import com.ruoyi.ems.service.IAreaBuildingZoningService;
import com.ruoyi.ems.service.IAreaService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 服务区Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-09
 */
@Service
public class AreaServiceImpl implements IAreaService {
    @Autowired
    private AreaMapper areaMapper;

    @Autowired
    private IAreaBuildingService buildingService;

    @Autowired
    private IAreaBuildingZoningService zoningService;

    /**
     * 查询服务区
     *
     * @param id 服务区主键
     * @return 服务区
     */
    @Override
    public Area selectAreaById(Long id) {
        return areaMapper.selectAreaById(id);
    }

    /**
     * 查询服务区
     *
     * @param code 服务区代码
     * @return 服务区
     */
    @Override
    public Area selectAreaByCode(String code) {
        return areaMapper.selectAreaByCode(code);
    }

    /**
     * 查询服务区列表
     *
     * @param area 服务区
     * @return 服务区
     */
    @Override
    public List<Area> selectAreaList(Area area) {
        return areaMapper.selectAreaList(area);
    }

    /**
     * 新增服务区
     *
     * @param area 服务区
     * @return 结果
     */
    @Override
    public int insertArea(Area area) {
        return areaMapper.insertArea(area);
    }

    /**
     * 修改服务区
     *
     * @param area 服务区
     * @return 结果
     */
    @Override
    public int updateArea(Area area) {
        return areaMapper.updateArea(area);
    }

    /**
     * 批量删除服务区
     *
     * @param ids 需要删除的服务区主键
     * @return 结果
     */
    @Override
    public int deleteAreaByIds(Long[] ids) {
        for (Long id : ids) {
            deleteRel(id);
        }

        return areaMapper.deleteAreaByIds(ids);
    }

    /**
     * 删除服务区信息
     *
     * @param id 服务区主键
     * @return 结果
     */
    @Override
    public int deleteAreaById(Long id) {
        deleteRel(id);
        return areaMapper.deleteAreaById(id);
    }

    @Override
    public List<TreeEntity> selectAreaTreeList(String tier) {
        List<TreeEntity> entities = null;

        if (StringUtils.equals(AreaTier.Area.name(), tier)) {
            List<Area> areas = areaMapper.selectAreaList(new Area());
            entities = areas.stream().map(TreeEntity::new).collect(Collectors.toList());
        }
        else if (StringUtils.equals(AreaTier.Building.name(), tier)) {
            List<Area> areas = areaMapper.selectAreaList(new Area());
            entities = areas.stream().map(TreeEntity::new).collect(Collectors.toList());
            entities.forEach(area -> area.setChildren(getAreaBuilding(area.getId())));
        }
        else if (StringUtils.equals(AreaTier.Zoning.name(), tier)) {
            List<Area> areas = areaMapper.selectAreaList(new Area());
            entities = areas.stream().map(TreeEntity::new).collect(Collectors.toList());
            entities.forEach(area -> {
                List<TreeEntity> buildings = getAreaBuilding(area.getId());
                buildings.forEach(building -> building.setChildren(getBuildingZoning(building.getId(), null)));
                area.setChildren(buildings);
            });
        }

        return entities;
    }

    @Override
    public List<TreeEntity> selectAreaTreeByCode(String tier, String code) {
        List<TreeEntity> retList = new ArrayList<>();

        if (StringUtils.equals(AreaTier.Area.name(), tier)) {
            Area area = areaMapper.selectAreaByCode(code);

            if (null != area) {
                TreeEntity entity = new TreeEntity(area);
                entity.setChildren(getAreaBuilding(code));
                entity.getChildren().forEach(building -> {
                    building.setChildren(getBuildingZoning(building.getId(), null));
                });

                retList.add(entity);
            }
        }
        else if (StringUtils.equals(AreaTier.Building.name(), tier)) {
            AreaBuilding building = buildingService.selectAreaBuildingByCode(code);

            if (null != building) {
                TreeEntity entity = new TreeEntity(building);
                entity.setChildren(getBuildingZoning(building.getBldgCode(), null));
                retList.add(entity);
            }
        }
        else if (StringUtils.equals(AreaTier.Zoning.name(), tier)) {
            AreaBuildingZoning zoning = zoningService.selectAreaBuildingZoningByCode(code);

            if (null != zoning) {
                TreeEntity entity = new TreeEntity(zoning);
                retList.add(entity);
            }
        }

        return retList;
    }

    @Override
    public List<TreeEntity> selectAreaTreeByTag(String tier, String tagCode) {
        List<TreeEntity> retList = new ArrayList<>();
        List<String> tagCodes = Arrays.asList(tagCode);

        if (StringUtils.equals(AreaTier.Zoning.name(), tier)) {
            List<Area> areas = areaMapper.selectAreaList(new Area());
            List<TreeEntity> entities = areas.stream().map(TreeEntity::new).collect(Collectors.toList());

            for (TreeEntity area : entities) {
                List<TreeEntity> dbBuildings = getAreaBuilding(area.getId());
                List<TreeEntity> buildings = new ArrayList<>();

                for (TreeEntity building : dbBuildings) {
                    List<TreeEntity> zonings = getBuildingZoning(building.getId(), tagCodes);

                    if (CollectionUtils.isNotEmpty(zonings)) {
                        building.setChildren(zonings);
                        buildings.add(building);
                    }
                }

                if (CollectionUtils.isNotEmpty(buildings)) {
                    area.setChildren(buildings);
                    retList.add(area);
                }
            }
        }

        return retList;
    }

    private void deleteRel(long id) {
        Area area = areaMapper.selectAreaById(id);

        if (null != area) {
            AreaBuilding buildingParam = new AreaBuilding();
            buildingParam.setAreaCode(area.getAreaCode());

            List<AreaBuilding> buildings = buildingService.selectAreaBuildingList(buildingParam);

            for (AreaBuilding building : buildings) {
                buildingService.deleteAreaBuilding(building);
            }
        }
    }

    private List<TreeEntity> getAreaBuilding(String areaCode) {
        AreaBuilding param = new AreaBuilding();
        param.setAreaCode(areaCode);
        List<AreaBuilding> areaBuildings = buildingService.selectAreaBuildingList(param);
        return areaBuildings.stream().map(TreeEntity::new).collect(Collectors.toList());
    }

    private List<TreeEntity> getBuildingZoning(String buildingCode, List<String> tagCodes) {
        AreaBuildingZoning param = new AreaBuildingZoning();
        param.setBldgCode(buildingCode);
        param.setTagCodeList(tagCodes);
        List<AreaBuildingZoning> zonings = zoningService.selectAreaBuildingZoningList(param);
        return zonings.stream().map(TreeEntity::new).collect(Collectors.toList());
    }
}
