package org.jeecg.modules.subwayNetwork.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.api.dto.PageSearch;
import org.jeecg.modules.homePage.vo.HomeSearchInfoVO;
import org.jeecg.modules.subwayNetwork.dto.LightRailQueryDTO;
import org.jeecg.modules.subwayNetwork.entity.LightRail;
import org.jeecg.modules.subwayNetwork.entity.LineAlias;
import org.jeecg.modules.subwayNetwork.mapper.LightRailMapper;
import org.jeecg.modules.subwayNetwork.mapper.LineAliasMapper;
import org.jeecg.modules.subwayNetwork.mapper.SubwaySectionMapper;
import org.jeecg.modules.subwayNetwork.mapper.TrainStationMapper;
import org.jeecg.modules.subwayNetwork.service.ILightRailService;
import org.jeecg.modules.subwayNetwork.vo.LightRailQueryVO;
import org.jeecg.modules.subwayNetwork.vo.SectionStationMapVO;
import org.jeecg.modules.subwayNetwork.vo.SectionStationNode;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 线路车站-线别管理
 */
@Service
public class LightRailServiceImpl extends ServiceImpl<LightRailMapper, LightRail> implements ILightRailService {

    @Resource
    private SubwaySectionMapper subwaySectionMapper;

    @Resource
    private TrainStationMapper trainStationMapper;

    @Resource
    private LineAliasMapper lineAliasMapper;

    @Override
    public IPage<LightRailQueryVO> queryPageList(PageSearch<LightRailQueryDTO> dto) {
        IPage<LightRailQueryVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());

        page = this.baseMapper.queryPageList(page, dto.getQuery());
        return page;
    }

    @Override
    public List<SectionStationMapVO> getSectionStation() {
        return this.baseMapper.getSectionStation();
    }

    public List<SectionStationNode> getTree2() {
        // 1. 查询数据
        // 1.1 查询所有线路,按上下行查询
        List<SectionStationNode> lightRailList = this.baseMapper.getTreeLightRailList();

        // 1.2 查询所有区间
        List<SectionStationNode> subwaySectionList = subwaySectionMapper.getTreeSubwaySectionList();

        // 1.3 查询所有车站
        List<SectionStationNode> trainStation = trainStationMapper.getTreeTrainStationList();


        // 2.组装数据
        // 2.1 组装 车站-区间&组装一个区间map
        Map<String, SectionStationNode> subwaySectionMap = new HashMap<>();
        for (SectionStationNode sectionStationNode : subwaySectionList) {

            // 2.1.1 组装区间map
            subwaySectionMap.put(sectionStationNode.getId(), sectionStationNode);


            // 2.1.2 组装车站-区间
            for (SectionStationNode lightRail : lightRailList) {
                if (sectionStationNode.getParent().equals(lightRail.getId())) {
                    List<SectionStationNode> children = lightRail.getChildren();
                    if (children == null) {
                        children = new ArrayList<>();
                        lightRail.setChildren(children);
                        lightRail.setIsLeaf(false);
                    }
                    children.add(sectionStationNode);
                }
            }

        }
        // 2.1 组装区间-车站数据
        for (SectionStationNode node : trainStation) {
            SectionStationNode sectionStationNode = subwaySectionMap.get(node.getParent());
            // 这个车站属于这个区间就添加进去,说明不是叶子节点
            if (sectionStationNode != null) {
                List<SectionStationNode> children = sectionStationNode.getChildren();
                if (children == null) {
                    children = new ArrayList<>();
                    sectionStationNode.setChildren(children);
                    sectionStationNode.setIsLeaf(false);
                }
                children.add(node);
            }
        }


        return lightRailList;
    }

    /**
     * 格式:
     * 线路1
     * |_
     * 线别1
     * |_
     * |  车站
     * |    |_车站1
     * |    ...
     * |    |_车站n
     * |_
     * 区间
     * |_区间1
     * ...
     * |_区间n
     *
     * @return
     */
    @Override
    public List<SectionStationNode> getTree() {
        // 1. 查询数据
        // 1.1 查询所有线路,按上下行查询
        List<SectionStationNode> lightRailList = this.baseMapper.getTreeLightRailList();

        // 1.2 查询上下行
        List<LineAlias> lineAliasRecords = lineAliasMapper.selectList(Wrappers.emptyWrapper());

        // 1.3 查询所有区间
        List<SectionStationNode> subwaySectionList = subwaySectionMapper.getTreeSubwaySectionList();

        // 1.4 查询所有车站
        List<SectionStationNode> trainStationList = trainStationMapper.getTreeTrainStationList();


        // 2. 组装数据
        List<SectionStationNode> lineAliasList = new ArrayList();
        // 2.1 组装线路->线别数据
        for (SectionStationNode lightRailNode : lightRailList) {
            List<SectionStationNode> childrens = new ArrayList<>();

            for (LineAlias lineAliasRecord : lineAliasRecords) {
                SectionStationNode children = new SectionStationNode();
                children.setId(lightRailNode.getId() + "-" + lineAliasRecord.getId());
                children.setLevel("2");
                children.setIsLeaf(true);
                children.setLabel(lineAliasRecord.getLineAliasName());
                children.setParent(lightRailNode.getId());
                children.setLineAliasId(lineAliasRecord.getId());
                children.setLineAliasCode(lineAliasRecord.getLineAliasCode());
                children.setStartMileage(BigDecimal.ZERO);
                children.setEndMileage(BigDecimal.ZERO);
                if (lineAliasRecord.getId().equals("1") || lineAliasRecord.getId().equals("2")) { // 上下行线单独处理
                    children.setStartMileage(lightRailNode.getStartMileage());
                    children.setCenterMileage(lightRailNode.getCenterMileage());
                    children.setEndMileage(lightRailNode.getEndMileage());
                }
                childrens.add(children);
                lineAliasList.add(children);
            }
            lightRailNode.setIsLeaf(false);
            lightRailNode.setChildren(childrens);
        }

        // 2.2
        // 2.2.1 组装区间
        if (ObjectUtil.isNotEmpty(subwaySectionList)) {
            // 定义一个虚拟区间map
            Map<String, SectionStationNode> virtualSectionMap = new HashMap<>();
            for (SectionStationNode sectionStationNode : subwaySectionList) {
                SectionStationNode virtualSectionNode = virtualSectionMap.get(sectionStationNode.getParent());


                if (virtualSectionNode == null) {
                    // 生成一个虚拟节点
                    virtualSectionNode = new SectionStationNode();
                    BeanUtil.copyProperties(sectionStationNode, virtualSectionNode);
                    String lineAliasId = sectionStationNode.getParent();
                    String virtualNodeId = "virtual_section_node_" + lineAliasId;
                    virtualSectionNode.setId(virtualNodeId);
                    virtualSectionNode.setLabel("区间");
                    virtualSectionNode.setLevel("3");
                    virtualSectionNode.setIsLeaf(false);


                    // 将属于这个线别的区间都归属到这个虚拟节点下面
                    sectionStationNode.setParent(virtualNodeId);
                    List<SectionStationNode> virtualSectionNodeChildren = new ArrayList<>();
                    virtualSectionNodeChildren.add(sectionStationNode);
                    virtualSectionNode.setChildren(virtualSectionNodeChildren);


                    virtualSectionMap.put(lineAliasId, virtualSectionNode);
                } else {
                    // 将属于这个线别的区间都归属到这个虚拟节点下面
                    sectionStationNode.setParent(virtualSectionNode.getId());
                    virtualSectionNode.getChildren().add(sectionStationNode);


                    // 改变当前虚拟节点的结束和中点里程，结束里程等于最后一个节点的节点结束里程
                    BigDecimal startMileage = virtualSectionNode.getStartMileage();
                    BigDecimal centerMileage;
                    BigDecimal endMileage = sectionStationNode.getEndMileage();
                    centerMileage = startMileage.add(endMileage).divide(new BigDecimal("2"), 3, RoundingMode.HALF_UP);
                    virtualSectionNode.setCenterMileage(centerMileage);
                    virtualSectionNode.setEndMileage(endMileage);
                }
            }

            // 将虚拟区间添加到线别
            for (SectionStationNode lineAliasNode : lineAliasList) {
                SectionStationNode virtualSectionNode = virtualSectionMap.get(lineAliasNode.getId());
                if (null != virtualSectionNode) {
                    lineAliasNode.setChildren(CollectionUtil.newArrayList(virtualSectionNode));
                    lineAliasNode.setIsLeaf(false);
                }
            }


        }


        // 2.2.2 组装车站
        if (ObjectUtil.isNotEmpty(trainStationList)) {
            // 定义一个虚拟车站map
            Map<String, SectionStationNode> virtualtrainStationMap = new HashMap<>();
            for (SectionStationNode trainStationNode : trainStationList) {
                SectionStationNode virtualTrainStationNode = virtualtrainStationMap.get(trainStationNode.getParent());


                if (virtualTrainStationNode == null) {
                    // 生成一个虚拟节点
                    virtualTrainStationNode = new SectionStationNode();
                    BeanUtil.copyProperties(trainStationNode, virtualTrainStationNode);
                    String lineAliasId = trainStationNode.getParent();
                    String virtualNodeId = "virtual_station_node_" + lineAliasId;
                    virtualTrainStationNode.setId(virtualNodeId);
                    virtualTrainStationNode.setLabel("车站");
                    virtualTrainStationNode.setLevel("3");
                    virtualTrainStationNode.setIsLeaf(false);


                    // 将属于这个线别的区间都归属到这个虚拟节点下面
                    trainStationNode.setParent(virtualNodeId);
                    List<SectionStationNode> virtualTrainStationNodeChildren = new ArrayList<>();
                    virtualTrainStationNodeChildren.add(trainStationNode);
                    virtualTrainStationNode.setChildren(virtualTrainStationNodeChildren);


                    virtualtrainStationMap.put(lineAliasId, virtualTrainStationNode);
                } else {
                    // 将属于这个线别的区间都归属到这个虚拟节点下面
                    trainStationNode.setParent(virtualTrainStationNode.getId());
                    virtualTrainStationNode.getChildren().add(trainStationNode);


                    // 改变当前虚拟节点的结束和中点里程，结束里程等于最后一个节点的节点结束里程
                    BigDecimal startMileage = trainStationNode.getStartMileage();
                    BigDecimal centerMileage;
                    BigDecimal endMileage = trainStationNode.getEndMileage();
                    centerMileage = startMileage.add(endMileage).divide(new BigDecimal("2"), 3, RoundingMode.HALF_UP);
                    virtualTrainStationNode.setCenterMileage(centerMileage);
                    virtualTrainStationNode.setEndMileage(endMileage);
                }
            }


            // 将虚拟车站添加到线别上面
            for (SectionStationNode lineAliasNode : lineAliasList) {
                SectionStationNode virtualSectionNode = virtualtrainStationMap.get(lineAliasNode.getId());
                if (null != virtualSectionNode) {
                    List<SectionStationNode> children = lineAliasNode.getChildren();
                    if (children == null) {
                        children = new ArrayList<>();
                    }
                    children.add(virtualSectionNode);
                    lineAliasNode.setChildren(children);
                    lineAliasNode.setIsLeaf(false);
                }
            }


        }







     /*   // 2.2
        // 2.2.1 组装车站,区间【车站1、车站1~车站2区间、车站2】
        Map<String, SectionStationNode> subwaySectionMap = subwaySectionList.stream().collect(Collectors.toMap(SectionStationNode::getId, value -> value));
        Map<String, List<SectionStationNode>> subwayAndtrainStationSectionMap = new HashMap<>();
        Map<String, SectionStationNode> useMap = new HashMap<>();
        for (SectionStationNode trainStation : trainStationList) {

            // ① 判断车站,区间list否存在,不存在新增一个
            List<SectionStationNode> subwayAndtrainStationNodeList = subwayAndtrainStationSectionMap.get(trainStation.getParent());
            if (subwayAndtrainStationNodeList == null) {
                subwayAndtrainStationNodeList = new ArrayList<>();
                subwayAndtrainStationSectionMap.put(trainStation.getParent(), subwayAndtrainStationNodeList);
            }
            subwayAndtrainStationNodeList.add(trainStation);


            // ② 紧接着去看看区间有没有，如果有则里面跟在车站后面
            String subwayId = trainStation.getId().split("-")[0]; // 区间id
            SectionStationNode sectionStationNode = subwaySectionMap.get(subwayId);
            SectionStationNode isUse = useMap.get(subwayId); // 这个map的作用是,一个线路下面的区间保证只能使用一次
            // 如果区间存在，并且没有被使用
            if (sectionStationNode != null) {
                if (isUse == null) {
                    // 将区间添加到车站后面
                    subwayAndtrainStationNodeList.add(sectionStationNode);

                    // 标记被使用
                    useMap.put(subwayId, sectionStationNode);
                } else {
                    // 如果被使用了,则要移除当前车站,避免重复,最后一个车站不用移除
                    // 车站-区间list去重,例如【站点1;站点1-站点2区间;站点2;站点2;站点2-站点3区间;站点3】去掉中间的重复的站点2
                    // 如果是最后一个车站则不用去重
                    subwayAndtrainStationNodeList.remove(trainStation);
                }
            }
        }


        // 2.2.2 组装线别数据->车站,区间【车站1、车站1~车站2区间、车站2】
        for (SectionStationNode lineAliasNode : lineAliasList) {
            List<SectionStationNode> childrens = subwayAndtrainStationSectionMap.get(lineAliasNode.getId());
            if (null != childrens) {
                lineAliasNode.setChildren(childrens);
                lineAliasNode.setIsLeaf(false);
            }
        }
*/
        return lightRailList;
    }

    @Override
    public List<HomeSearchInfoVO> searchInfo(String query) {
        return this.baseMapper.searchInfo(query);
    }
}
