package com.ningdatech.carapi.sys.convert;

import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;

import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.carapi.car.equipment.model.DataAccessDevices;
import com.ningdatech.carapi.car.equipment.model.NdVehicleEquipmentChannels;
import com.ningdatech.carapi.car.equipment.model.NdVehicleEquipmentInfo;
import com.ningdatech.carapi.sys.entity.Region;
import com.ningdatech.carapi.sys.entity.dto.RegionDTO;
import com.ningdatech.carapi.sys.entity.dto.RegionTreeDTO;
import com.ningdatech.carapi.sys.entity.vo.CarVO;
import com.ningdatech.carapi.sys.entity.vo.RegionCompanyCarTreeVo;
import com.ningdatech.carapi.sys.entity.vo.RegionTreeCompanyVO;
import com.ningdatech.carapi.sys.entity.vo.RegionTreeVO;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * <p>
 * RegionConverter
 * </p>
 *
 * @author WendyYang
 * @since 10:31 2022/10/12
 */
public class RegionConverter {

    public static RegionDTO toRegionDTO(Region region) {
        RegionDTO dto = new RegionDTO();
        dto.setRegionLevel(region.getLevel());
        dto.setRegionName(region.getName());
        dto.setParentCode(region.getParentCode());
        dto.setRegionCode(region.getRegionCode());
        dto.setId(region.getId());
        dto.setMapData(region.getMapData());
        dto.setDeleted(region.getDeleted());
        dto.setGovUnit(region.getGovUnit());
        dto.setParentId(region.getParentId());
        dto.unionCode();
        return dto;
    }

    public static List<RegionTreeDTO> toRegionTreeDTOList(List<RegionDTO> regionDTOList) {
        if (CollectionUtils.isEmpty(regionDTOList)) {
            return new ArrayList<>();
        }
        return regionDTOList.stream().map(RegionConverter::toRegionTreeDTO).collect(Collectors.toList());
    }

    public static RegionTreeDTO toRegionTreeDTO(RegionDTO regionDTO) {
        RegionTreeDTO treeDto = new RegionTreeDTO();
        treeDto.setLevel(regionDTO.getRegionLevel());
        treeDto.setName(regionDTO.getRegionName());
        treeDto.setParentCode(regionDTO.getParentCode());
        treeDto.setRegionCode(regionDTO.getRegionCode());
        treeDto.setUnionCode(regionDTO.getUnionCode());
        treeDto.setId(regionDTO.getId());
        treeDto.setMapData(regionDTO.getMapData());
        treeDto.setDeleted(regionDTO.getDeleted());
        treeDto.setGovUnit(regionDTO.getGovUnit());
        return treeDto;
    }

    public static List<RegionTreeVO> toRegionTree(Long parentId, Map<Long, List<RegionDTO>> regions,
        boolean showDeleted, Map<Long, List<CarVO>> carNoList, Map<Long, List<RegionTreeCompanyVO>> companyMap) {
        List<RegionTreeVO> treeList = new ArrayList<>();
        List<RegionDTO> children = regions.getOrDefault(parentId, Collections.emptyList());
        for (RegionDTO region : children) {
            if (!showDeleted && region.getDeleted()) {
                continue;
            }
            RegionTreeVO treeNode = new RegionTreeVO();
            treeNode.setLevel(region.getRegionLevel());
            treeNode.setName(region.getRegionName());
            treeNode.setParentCode(region.getParentCode());
            treeNode.setRegionCode(region.getRegionCode());
            List<RegionDTO> regionList = regions.get(region.getId());
            if (CollectionUtils.isNotEmpty(regionList)) {
                treeNode.setChildren(toRegionTree(region.getId(), regions, showDeleted, carNoList, companyMap));
            }

            if (companyMap != null) {
                List<RegionTreeCompanyVO> companyList = companyMap.get(region.getId());
                treeNode.setCompanyList(ObjectUtil.defaultIfNull(companyList, Collections.emptyList()));
                if (treeNode.getCompanyList().size() > 0 && carNoList != null) {
                    treeNode.getCompanyList().forEach(company -> {
                        List<CarVO> carNos = carNoList.getOrDefault(company.getId(), Collections.emptyList());
                        company.setCarNoList(carNos);
                    });
                }
            }
            treeNode.setMapData(region.getMapData());
            treeNode.setId(region.getId());
            treeNode.setUnionCode(region.getUnionCode());
            treeNode.setGovUnit(region.getGovUnit());
            treeList.add(treeNode);
        }
        return treeList;
    }

    public static List<RegionCompanyCarTreeVo> toRegionCompanyCarNoTree(Long parentId,
                                                                        Map<Long, List<RegionDTO>> regions, boolean showDeleted, Map<Long, List<Pair<Long, CarVO>>> carNoList,
                                                                        Map<Long, List<RegionTreeCompanyVO>> companyMap, Map<String, DataAccessDevices> deviceMap,
                                                                        Map<String, List<NdVehicleEquipmentInfo>> equipmentMap, Map<Long, NdVehicleEquipmentChannels> channelsMap) {
        List<RegionCompanyCarTreeVo> treeList = new ArrayList<>();
        List<RegionDTO> children = regions.getOrDefault(parentId, Collections.emptyList());
        for (RegionDTO region : children) {
            if (!showDeleted && region.getDeleted()) {
                continue;
            }
            RegionCompanyCarTreeVo regionNode = new RegionCompanyCarTreeVo();
            regionNode.setCode(region.getId());
            regionNode.setValue(region.getRegionName());
            regionNode.setType(RegionCompanyCarTreeVo.Type.REGION);
            regionNode.setLevel(region.getRegionLevel());
            regionNode.setUnique();
            if (companyMap != null) {
                List<RegionCompanyCarTreeVo> companies = null;
                List<RegionTreeCompanyVO> companyList = companyMap.get(region.getId());
                boolean hasCompany = CollectionUtils.isNotEmpty(companyList);
                if (hasCompany) {
                    companies = CollUtils.convert(companyList, w -> {
                        RegionCompanyCarTreeVo company = new RegionCompanyCarTreeVo();
                        company.setCode(w.getId());
                        company.setValue(w.getName());
                        company.setType(RegionCompanyCarTreeVo.Type.COMPANY);
                        company.setUnique();
                        return company;
                    });
                    regionNode.getChildren().addAll(companies);
                }
                if (hasCompany && carNoList != null) {
                    companies.forEach(company -> {
                        List<Pair<Long, CarVO>> carNos = carNoList.get(company.getCode());
                        if (CollectionUtils.isNotEmpty(carNos)) {
                            List<RegionCompanyCarTreeVo> carNodes = CollUtils.convert(carNos, w -> {
                                CarVO car = w.getValue();
                                RegionCompanyCarTreeVo carNo = new RegionCompanyCarTreeVo();
                                carNo.setCode(w.getKey());
                                carNo.setValue(car.getCarPlate());
                                carNo.setStatus(car.getStatus());
                                carNo.setMoving(car.getMoving());
                                carNo.setType(RegionCompanyCarTreeVo.Type.CAR_NO);
                                carNo.setUnique();
                                return carNo;
                            });
                            company.getChildren().addAll(carNodes);

                            carNodes.forEach(car -> {
                                List<NdVehicleEquipmentInfo> equipmentInfos = equipmentMap.get(car.getValue());
                                if (CollUtil.isNotEmpty(equipmentInfos)) {
                                    List<RegionCompanyCarTreeVo> equipNodes = CollUtils.convert(equipmentInfos, e -> {
                                        RegionCompanyCarTreeVo equip = new RegionCompanyCarTreeVo();
                                        equip.setDeviceId(e.getEquipmentNo());
                                        NdVehicleEquipmentChannels channels =
                                            channelsMap.get((e.getId()));
                                        equip.setValue(channels.getName());
                                        // 根据平台ID和视频设备编号判断视频是否可以播放
                                        DataAccessDevices devices =
                                            deviceMap.get(e.getEquipmentNo() + e.getPlatformId());
                                        if (Objects.nonNull(devices) && devices.getStatus() != null
                                            && !StrPool.EMPTY.equals(devices.getStatus())) {
                                            equip.setVideoStatus(devices.getStatus());
                                        } else {
                                            equip.setVideoStatus("OFF");
                                        }
                                        equip.setUnique();
                                        equip.setType(RegionCompanyCarTreeVo.Type.CAR_VIDEO);
                                        return equip;
                                    });
                                    car.getChildren().addAll(equipNodes);
                                }
                            });
                        }
                    });

                }
            }
            // 设置子节点信息
            List<RegionDTO> regionList = regions.get(region.getId());
            if (CollectionUtils.isNotEmpty(regionList)) {
                regionNode.getChildren().addAll(toRegionCompanyCarNoTree(region.getId(), regions, showDeleted,
                    carNoList, companyMap, deviceMap, equipmentMap, channelsMap));
            }
            treeList.add(regionNode);
        }
        return treeList;
    }
}
