package com.ozs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ozs.common.utils.AppendUtils;
import com.ozs.entity.*;
import com.ozs.entity.vo.BaseCameraManagementDto;
import com.ozs.entity.vo.BaseVehicleTerminalDto;
import com.ozs.entity.vo.CameraTreeVo;
import com.ozs.entity.vo.VehicleTreeVo;
import com.ozs.mapper.*;
import com.ozs.service.BaseDeviceDynamicManagementService;
import com.ozs.service.VehiclePositionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

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

/**
 * <p>
 * 设备动态管理表 服务实现类
 * </p>
 *
 * @author ozs
 * @since 2023-02-22
 */
@Service
public class BaseDeviceDynamicManagementServiceImpl extends ServiceImpl<BaseDeviceDynamicManagementMapper, BaseDeviceDynamicManagement> implements BaseDeviceDynamicManagementService {
    @Autowired
    BaseDeviceDynamicManagementMapper baseDeviceDynamicManagementMapper;
    @Autowired
    BaseRailwayManagementMapper railwayManagementMapper;

    @Autowired
    BaseTerminalMapper baseTerminalMapper;
    @Autowired
    VehiclePositionMapper vehiclePositionMapper;
    @Autowired
    BaseVehicleTerminalMapper baseVehicleTerminalMapper;
    @Autowired
    BaseVehicleMapper baseVehicleMapper;

    @Override
    public CameraTree cameraTree(CameraTreeVo cameraTreeVo) {


        //1 父
        CameraTree cameraTree = CameraTree.builder()
                .name("相机树")
                .code("0")
                .flay(false)
                .children(new ArrayList<>())
                .build();
        Map<String, CameraTree> map = new HashMap<>();
        List<BaseCameraManagementDto> list = baseDeviceDynamicManagementMapper.list(cameraTreeVo);
        if (list.size() > 0) {
            for (BaseCameraManagementDto o : list) {
                // 线路
                CameraTree build = CameraTree.builder()
                        .code(o.getRailwayCode())
                        .name(o.getRailwayName())
                        .flay(true)
                        .children(new ArrayList<>())
                        .build();

                if (!cameraTree.getChildren().stream()
                        .map(CameraTree::getCode)
                        .collect(Collectors.toList())
                        .contains(build.getCode())) {
                    cameraTree.getChildren().add(build);
                    map.put(o.getRailwayCode(), build);
                }

                // 里程
                String mils = AppendUtils.stringAppend(o.getInstallMile());
                CameraTree build1 = CameraTree.builder()
                        .code(mils + "-" + (o.getLineDir().equals("1") ? "上行" : "下行"))
                        .name(mils + "-" + (o.getLineDir().equals("1") ? "上行" : "下行"))
                        .flay(true)
                        .mileage(o.getInstallMile())
                        .children(new ArrayList<>())
                        .build();


                if (!ObjectUtils.isEmpty(map.get(o.getRailwayCode()))) {
                    CameraTree cameraTree1 = map.get(o.getRailwayCode() + "-" + o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行"));
                    if (ObjectUtils.isEmpty(cameraTree1)) {
                        map.put(o.getRailwayCode() + "-" + o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行"), build1);
                        map.get(o.getRailwayCode()).getChildren().add(build1);
                    }
                }

                // 摄像头
                CameraTree build2 = CameraTree.builder()
                        .code(o.getCameraCode())
                        .name(o.getCameraCode())
                        .flay(true)
                        .children(new ArrayList<>())
                        .build();


                if (!ObjectUtils.isEmpty(map.get(o.getRailwayCode() + "-" + o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行")))) {
                    map.get(o.getRailwayCode() + "-" + o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行")).getChildren().add(build2);
                }
            }
        }

        return cameraTree;
    }

    @Override
    public VehicleTree vehicleTree(VehicleTreeVo vehicleTreeVo) {
        //1 父
        ArrayList<VehicleTree> children = new ArrayList<>();
        VehicleTree vehicleTree = VehicleTree.builder()
                .name("机车树")
                .code("0")
                .flay(false)
                .children(children)
                .build();

        // 符合条件的终端行驶记录信息
        List<VehiclePosition> list = new ArrayList<>();


        // 终端数据
        List<BaseTerminal> baseTerminals = baseTerminalMapper.selectList(new LambdaQueryWrapper<>());
        if (!ObjectUtils.isEmpty(baseTerminals)) {
            for (BaseTerminal baseTerminal : baseTerminals) {
                // 查询所有的终端在行驶记录表的最后一个数据
                LambdaQueryWrapper<VehiclePosition> lambdaQueryWrapper = new LambdaQueryWrapper();
                lambdaQueryWrapper.eq(VehiclePosition::getTerminalCode, baseTerminal.getTerminalCode());
                lambdaQueryWrapper.orderByDesc(VehiclePosition::getId);
                List<VehiclePosition> vehiclePositions = vehiclePositionMapper.selectList(lambdaQueryWrapper);
                if (!ObjectUtils.isEmpty(vehiclePositions) && vehiclePositions.size() > 0) {
                    //todo: 判断公里数和上行下行
                    if (ObjectUtils.isEmpty(vehicleTreeVo.getMils())
                            && ObjectUtils.isEmpty(vehicleTreeVo.getLineDir())) {
                        //都为空
                        list.add(vehiclePositions.get(0));
                    } else if (!ObjectUtils.isEmpty(vehicleTreeVo.getMils())
                            && vehicleTreeVo.getMils().equals(vehiclePositions.get(0).getTravelMile() + "")
                            && !ObjectUtils.isEmpty(vehicleTreeVo.getLineDir())
                            && vehicleTreeVo.getLineDir().equals(vehiclePositions.get(0).getLineDir())
                    ) {
                        //都不为空
                        list.add(vehiclePositions.get(0));
                    } else if (!ObjectUtils.isEmpty(vehicleTreeVo.getMils())
                            && vehicleTreeVo.getMils().equals(vehiclePositions.get(0).getTravelMile() + "")
                            && ObjectUtils.isEmpty(vehicleTreeVo.getLineDir())) {
                        //里程不为空，线路为空
                        list.add(vehiclePositions.get(0));
                    } else if (!ObjectUtils.isEmpty(vehicleTreeVo.getLineDir())
                            && vehicleTreeVo.getLineDir().equals(vehiclePositions.get(0).getLineDir())
                            && ObjectUtils.isEmpty(vehicleTreeVo.getMils())) {
                        //里程不为空，线路为空
                        list.add(vehiclePositions.get(0));
                    }

                }
            }
        }

        // 线路
        List<BaseRailwayManagement> railwayList = railwayManagementMapper.selectList(new LambdaQueryWrapper());
        if (!ObjectUtils.isEmpty(railwayList)) {
            for (BaseRailwayManagement baseRailwayManagement : railwayList) {
                if (StringUtils.isBlank(vehicleTreeVo.getRailwayCode())) {
                    //  根据线路查询当前机车行驶
                    VehicleTree build = VehicleTree.builder()
                            .code(baseRailwayManagement.getRailwayCode())
                            .name(baseRailwayManagement.getRailwayName())
                            .flay(true)
                            .children(new ArrayList<>())
                            .build();
                    if (list.size() > 0) {
                        List<VehiclePosition> collect = list.stream().filter(vp -> vp.getRailwayCode().equals(baseRailwayManagement.getRailwayCode())).collect(Collectors.toList());
                        if (!ObjectUtils.isEmpty(collect)) {
                            collect.sort((o1, o2) -> o1.getTravelMile().compareTo(o2.getTravelMile()));
                            List<VehicleTree> childrens = collect.stream().map(vp -> {
                                LambdaQueryWrapper<BaseVehicle> lambdaQueryWrapper = new LambdaQueryWrapper();
                                lambdaQueryWrapper.eq(BaseVehicle::getVehicleCode, vp.getVehicleCode());
                                BaseVehicle baseVehicle = baseVehicleMapper.selectOne(lambdaQueryWrapper);
                                return VehicleTree.builder()
                                        .code(vp.getTerminalCode())
                                        .name(AppendUtils.stringAppend(Integer.valueOf(vp.getTravelMile())) + "-" + (vp.getLineDir().equals("1") ? "上行" : "下行") + "-" + (ObjectUtils.isEmpty(baseVehicle) ? vp.getVehicleCode() : baseVehicle.getVehicleName()))
                                        .mileage(vp.getTravelMile())
                                        .flay(true)
                                        .children(new ArrayList<>())
                                        .build();
                            }).collect(Collectors.toList());
                            build.setChildren(childrens);
                        }
                    }
                    children.add(build);
                } else if (!StringUtils.isBlank(vehicleTreeVo.getRailwayCode()) && vehicleTreeVo.getRailwayCode().equals(baseRailwayManagement.getRailwayCode())) {
                    //  根据线路查询当前机车行驶
                    VehicleTree build = VehicleTree.builder()
                            .code(baseRailwayManagement.getRailwayCode())
                            .name(baseRailwayManagement.getRailwayName())
                            .flay(true)
                            .children(new ArrayList<>())
                            .build();
                    if (list.size() > 0) {
                        List<VehiclePosition> collect = list.stream().filter(vp -> vp.getRailwayCode().equals(baseRailwayManagement.getRailwayCode())).collect(Collectors.toList());
                        if (!ObjectUtils.isEmpty(collect)) {
                            collect.sort((o1, o2) -> o1.getTravelMile().compareTo(o2.getTravelMile()));
                            List<VehicleTree> childrens = collect.stream().map(vp -> {
                                LambdaQueryWrapper<BaseVehicle> lambdaQueryWrapper = new LambdaQueryWrapper();
                                lambdaQueryWrapper.eq(BaseVehicle::getVehicleCode, vp.getVehicleCode());
                                BaseVehicle baseVehicle = baseVehicleMapper.selectOne(lambdaQueryWrapper);
                                return VehicleTree.builder()
                                        .code(vp.getTerminalCode())
                                        .name(AppendUtils.stringAppend(Integer.valueOf(vp.getTravelMile())) + "-" + (vp.getLineDir().equals(1) ? "上行" : "下行") + "-" + (ObjectUtils.isEmpty(baseVehicle) ? vp.getVehicleCode() : baseVehicle.getVehicleName()))
                                        .flay(true)
                                        .mileage(vp.getTravelMile())
                                        .children(new ArrayList<>())
                                        .build();
                            }).collect(Collectors.toList());
                            build.setChildren(childrens);
                        }
                    }
                    children.add(build);
                }

            }
        }


        vehicleTree.setChildren(children);

        return vehicleTree;
    }

    @Override
    public List<Object> getPlayInfoByTerminalCode(String terminalCode) {
        List<Object> list = new ArrayList<>();
        LambdaQueryWrapper<VehiclePosition> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(VehiclePosition::getTerminalCode, terminalCode);
        lambdaQueryWrapper.orderByDesc(VehiclePosition::getId);
        List<VehiclePosition> vehiclePositions = vehiclePositionMapper.selectList(lambdaQueryWrapper);
        if (!ObjectUtils.isEmpty(vehiclePositions) && vehiclePositions.size() > 0) {
            LambdaQueryWrapper<BaseRailwayManagement> lambdaQueryWrapper1 = new LambdaQueryWrapper();
            lambdaQueryWrapper1.eq(BaseRailwayManagement::getRailwayCode, vehiclePositions.get(0).getRailwayCode());
            BaseRailwayManagement baseRailwayManagement = railwayManagementMapper.selectOne(lambdaQueryWrapper1);
            list.add(!ObjectUtils.isEmpty(baseRailwayManagement) ? baseRailwayManagement.getRailwayName() : "线路不存在");
            list.add(AppendUtils.stringAppend(vehiclePositions.get(0).getTravelMile()));
            list.add(vehiclePositions.get(0).getLineDir());
            list.add(terminalCode);
        }
        list.add(100);
        list.add(1);
        return list;
    }
}
