package com.zhgd.xmgl.modules.basicdata.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhgd.xmgl.modules.basicdata.dto.MonitorTreeDto;
import com.zhgd.xmgl.modules.basicdata.entity.Engineering;
import com.zhgd.xmgl.modules.basicdata.entity.Project;
import com.zhgd.xmgl.modules.basicdata.entity.MonitorDev;
import com.zhgd.xmgl.modules.basicdata.mapper.EngineeringMapper;
import com.zhgd.xmgl.modules.basicdata.mapper.MonitorDevMapper;
import com.zhgd.xmgl.modules.basicdata.service.IMonitorDevService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @Description: 视频管理表
 * @author： pds
 * @date：   2023-02-27
 * @version： V1.0
 */
@Service
public class MonitorDevServiceImpl extends ServiceImpl<MonitorDevMapper, MonitorDev> implements IMonitorDevService {

    @Autowired
    private EngineeringMapper engineeringMapper;

    @Override
    public Page<MonitorDev> pageListByEnterprise(Page page, Wrapper<MonitorDev> wrapper) {
        return baseMapper.pageListByEnterprise(page, wrapper);
    }

    @Override
    public List<MonitorTreeDto> getMonitorTreeByProject(List<Project> projectList) {
        List<String> projectSns = projectList.stream().map(p -> p.getProjectSn()).collect(Collectors.toList());
        List<Engineering> engineeringList = engineeringMapper.selectList(Wrappers.<Engineering>lambdaQuery().in(Engineering::getProjectSn, projectSns));
        LambdaQueryWrapper<MonitorDev> wrapper = Wrappers.<MonitorDev>lambdaQuery();
        if (projectSns.size() > 0) {
            wrapper.in(MonitorDev::getProjectSn, projectSns);
        }
        wrapper.orderByAsc(MonitorDev::getPriority);
        List<MonitorDev> monitorDevList = this.list(wrapper);
        List<MonitorTreeDto> monitorTreeDtos = new ArrayList<>();
        projectList.stream().forEach(p -> {
            MonitorTreeDto monitorTreeDto = new MonitorTreeDto();
            monitorTreeDto.setId(p.getProjectId());
            monitorTreeDto.setName(p.getProjectName());
            monitorTreeDto.setType(1);
            List<MonitorTreeDto> engineeringChildren = getEngineeringList(engineeringList, p.getProjectSn(), null, monitorDevList);
            List<MonitorTreeDto> projectMonitor = buildMonitorTree(1, p.getProjectSn(), monitorDevList);
            engineeringChildren.addAll(projectMonitor);
            monitorTreeDto.setChildren(engineeringChildren);
            monitorTreeDtos.add(monitorTreeDto);
        });
        return monitorTreeDtos;
    }

    @Override
    public List<MonitorTreeDto> getMonitorTreeByEngineering(List<Engineering> engineeringList) {
        return getMonitorTreeByEngineering(engineeringList, "");
    }

    @Override
    public List<MonitorTreeDto> getMonitorTreeByEngineering(List<Engineering> engineeringList, String monitorName) {
        List<String> engineeringSns = engineeringList.stream().map(e -> e.getEngineeringSn()).collect(Collectors.toList());
        LambdaQueryWrapper<MonitorDev> wrapper = Wrappers.<MonitorDev>lambdaQuery();
        if (engineeringSns.size() > 0) {
            wrapper.in(MonitorDev::getEngineeringSn, engineeringSns).orderByAsc(MonitorDev::getPriority);
        }
        if (StringUtils.isNotBlank(monitorName)) {
            wrapper.like(MonitorDev::getName, monitorName);
        }
        List<MonitorDev> monitorDevs = this.list(wrapper);
        return getEngineeringList(engineeringList, "0", monitorName, monitorDevs);
    }

    private List<MonitorTreeDto> getEngineeringList(List<Engineering> engineeringList, String parentId, String monitorName, List<MonitorDev> monitorDevList) {
        if (!parentId.equals("0")) {
            List<String> engineeringSns = engineeringList.stream().map(e -> e.getEngineeringSn()).collect(Collectors.toList());
            if (engineeringSns.size() > 0) {
                monitorDevList = monitorDevList.stream().filter(m -> engineeringSns.contains(m.getEngineeringSn())).collect(Collectors.toList());
            }
            if (StringUtils.isNotBlank(monitorName)) {
                monitorDevList = monitorDevList.stream().filter(m -> m.getName().contains(monitorName)).collect(Collectors.toList());
            }
        }
        List<MonitorTreeDto> monitorTreeDtos = new ArrayList<>();
        List<MonitorDev> monitorDevs = monitorDevList;
        engineeringList.stream().forEach(e -> {
            MonitorTreeDto monitorTreeDto = new MonitorTreeDto();
            monitorTreeDto.setId(e.getId());
            monitorTreeDto.setName(e.getEngineeringName());
            monitorTreeDto.setParentId(parentId);
            monitorTreeDto.setType(2);
            monitorTreeDto.setChildren(buildMonitorTree(2, e.getEngineeringSn(), monitorDevs));
            monitorTreeDtos.add(monitorTreeDto);
        });
        return monitorTreeDtos;
    }


    private List<MonitorTreeDto> buildMonitorTree(Integer type, String parentId, List<MonitorDev> monitorDevs) {
        List<MonitorDev> children = new ArrayList<>();
        if (type == 1) {
            children = monitorDevs.stream().filter(p -> p.getProjectSn().equals(parentId) && StringUtils.isBlank(p.getEngineeringSn())).collect(Collectors.toList());
        } else if (type == 2) {
            children = monitorDevs.stream().filter(p -> p.getEngineeringSn().equals(parentId)).collect(Collectors.toList());
        }
        List<MonitorTreeDto> monitorTreeDtos = new ArrayList<>();
        children.stream().forEach(p -> {
            MonitorTreeDto monitorTreeDto = new MonitorTreeDto();
            monitorTreeDto.setId(p.getMonitorId());
            monitorTreeDto.setName(p.getName());
            monitorTreeDto.setParentId(parentId);
            monitorTreeDto.setType(3);
            monitorTreeDtos.add(monitorTreeDto);
        });
        return monitorTreeDtos;
    }
}
