package com.zd.laboratory.controller;

import cn.hutool.core.collection.CollUtil;
import com.zd.common.core.enums.HardwareTypeEnum;
import com.zd.common.core.utils.poi.ExcelUtil;
import com.zd.common.core.web.controller.BaseController;
import com.zd.common.core.web.domain.AjaxResult;
import com.zd.common.core.web.domain.ResultData;
import com.zd.common.core.web.page.TableDataInfo;
import com.zd.common.log.annotation.Log;
import com.zd.common.log.enums.BusinessType;
import com.zd.laboratory.domain.LabBuilding;
import com.zd.laboratory.domain.LabHardware;
import com.zd.laboratory.domain.LabSensor;
import com.zd.laboratory.domain.LabSubject;
import com.zd.laboratory.domain.vo.LabBuildingInfoVO;
import com.zd.laboratory.domain.vo.LabBuildingVO;
import com.zd.laboratory.domain.vo.LabSubjectDetailVO;
import com.zd.laboratory.domain.vo.LabSubjectLayoutVo;
import com.zd.laboratory.mapper.LabHardwareMapper;
import com.zd.laboratory.mapper.LabSensorMapper;
import com.zd.laboratory.service.ILabBuildingService;
import com.zd.laboratory.service.ILabSubjectLayoutService;
import com.zd.laboratory.service.ILabSubjectService;
import com.zd.laboratory.service.impl.LabSubjectManagerService;
import com.zd.system.api.laboratory.domain.SensorFunctionStatus;
import com.zd.system.api.laboratory.domain.SubAddrr;
import com.zd.system.api.laboratory.domain.vo.HardwareCVO;
import com.zd.system.api.laboratory.domain.vo.LabSubClassVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 楼层Controller
 *
 * @author zd
 * @date 2021-09-01
 */
@Api(tags = "楼层")
@RestController
@RequestMapping("/building")
public class LabBuildingController extends BaseController {
    @Autowired
    private ILabBuildingService labBuildingService;
    @Autowired
    LabSensorMapper sensorMapper;
    @Autowired
    LabSubjectManagerService labSubjectManagerService;

    @Autowired
    ILabSubjectService subjectService;
    @Autowired
    ILabSubjectLayoutService subjectLayoutService;
    /**
     * 最低危险等级
     */
//    @Autowired
//    private LabSubClassVO getNONELabSubClassVO;

    @Autowired
    LabHardwareMapper hardwareMapper;

    @Autowired
    LabSubjectManagerService subjectManagerService;

    /**
     * 查询楼栋列表
     */
    @GetMapping("/list")
    @ApiOperation("查询楼栋列表分页")
    public TableDataInfo list(LabBuilding labBuilding) {
        startPage();
        List<LabBuilding> list = labBuildingService.selectLabBuildingList(labBuilding);
        return getDataTable(list);
    }

    /**
     * 查询楼层-不分页
     */
    @GetMapping("/{deptId}/list")
    public ResultData<List<LabBuilding>> list(@PathVariable("deptId") Long deptId) {
        LabBuilding labBuilding = new LabBuilding();
        labBuilding.setDeptId(deptId);
        List<LabBuilding> list = labBuildingService.selectLabBuildingList(labBuilding);
        return ResultData.success(list);
    }


    /**
     * 导出楼栋列表
     */
    @Log(title = "楼栋", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, LabBuilding labBuilding) throws IOException {
        List<LabBuilding> list = labBuildingService.selectLabBuildingList(labBuilding);
        ExcelUtil<LabBuilding> util = new ExcelUtil<LabBuilding>(LabBuilding.class);
        util.exportExcel(response, list, "楼栋数据");
    }

    /**
     * 获取楼栋详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(labBuildingService.selectLabBuildingById(id));
    }

    /**
     * 新增楼栋
     */
    @Log(title = "楼栋", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody LabBuilding labBuilding) {
        return toAjax(labBuildingService.insertLabBuilding(labBuilding));
    }

    /**
     * 修改楼栋
     */
    @Log(title = "楼栋", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody LabBuilding labBuilding) {
        return toAjax(labBuildingService.updateLabBuilding(labBuilding));
    }

    /**
     * 删除楼栋
     */
    @Log(title = "楼栋", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(labBuildingService.deleteLabBuildingByIds(ids));
    }


    /**
     * 查询楼栋列表(不分页)
     */
    @GetMapping("/getBuildLlist")
    @ApiOperation("查询楼栋列表")
    public AjaxResult getBuildLlist(LabBuilding labBuilding) {
        List<LabBuilding> list = labBuildingService.getBuildLlist(labBuilding);
        return AjaxResult.success(list);
    }

    /**
     * 实验室布局图列表
     */
    @GetMapping("/lablayout")
    public AjaxResult labLayout(LabBuildingVO labBuilding) {
        List<Map<String, Object>> allMap = labBuildingService.labLayout(labBuilding);
        return AjaxResult.success(allMap);
    }

    /**
     * 数据大屏实验室以及信息布局图
     */
    @GetMapping("/labInfoLayout")
    @ApiOperation(value = "数据大屏实验室以及信息布局图")
    public AjaxResult labInfoLayout(LabBuildingVO labBuilding) {
        List<LabBuildingInfoVO> allMap = labBuildingService.labInfoLayout(labBuilding);
        //传感器功能列表
        List<LabSubject> labSubjects = new ArrayList <>();
        for(LabBuildingInfoVO build:allMap){
            for(LabSubjectLayoutVo layout:build.getLayouts()){
                if(layout.getSubjectDetail()!=null){
                    LabSubjectDetailVO subject = layout.getSubjectDetail();
                    labSubjects.add(subject);
                }
            }
        }
        Long[] longs = labSubjects.stream().map(a -> a.getId()).toArray(Long[]::new);
        //2.获取传感器
        List<LabSensor> labSensors = sensorMapper.selectSensorBySubIds(longs);

        Map<Long, List<LabSensor>> mapSenseTemp = Optional.ofNullable(labSensors)
                .orElse(Arrays.asList())
                .stream()
                .collect(Collectors.groupingBy(LabSensor::getSubjectId));

        for(LabBuildingInfoVO build:allMap){
            for(LabSubjectLayoutVo layout:build.getLayouts()){
                if(layout.getSubjectDetail()!=null){
                    List<LabSensor> sensorList = mapSenseTemp.get(layout.getSubjectDetail().getId());
                    List<SensorFunctionStatus> sensorFunctionStatuses = subjectManagerService.getSensorFunctionStatuses(sensorList,true);
                    layout.getSubjectDetail().setSensorFunctionStatuses(sensorFunctionStatuses);
                }
            }
        }


//        List<SensorFunctionStatus> sensorFunctionStatuseList =  labSubjects.stream().map(a -> {
//            List<LabSensor> labSensors1 = mapSenseTemp.get(a.getId());
//            List<SensorFunctionStatus> sensorFunctionStatuses = subjectManagerService.getSensorFunctionStatuses(labSensors1,true);
//            return sensorFunctionStatuses;
//        }).collect(Collectors.toList());

//        subjectManagerService.createSubControllerVO(labSubjects,false,true,true,false,true);



        //增加危险等级
        List<LabSubClassVO> labSubClassVOS = null;

        //增加地址
        List<Long> layoutids = new ArrayList<>();

        Map<Long,LabSubjectDetailVO> temp = new HashMap<>();
        List<Long> collect = Optional.ofNullable(allMap)
                .filter(a -> a.size() > 0)
                .orElseGet(Collections::emptyList)
                .stream()
                .flatMap(a -> Optional.ofNullable(a.getLayouts())
                            .filter(c -> c.size() > 0)
                            .orElseGet(Collections::emptyList)
                            .stream()
                            .filter(c -> c.getSubjectDetail() != null)
                            .filter(c -> c.getSubjectDetail().getId() != null)
                            .map(c -> {
                                if(c.getSubjectDetail().getLayoutId()!=null)
                                {
                                    layoutids.add(c.getSubjectDetail().getLayoutId());
                                }
                                //c.getSubjectDetail().setSubClassVO(getNONELabSubClassVO);
                                //缓存当前对象,减少循环
                                temp.put(c.getSubjectDetail().getId(),c.getSubjectDetail());
                                return   c.getSubjectDetail().getId();
                            })
                )
                .distinct()
                .collect(Collectors.toList());
        if(CollUtil.isNotEmpty(collect))
        {
            //危险等级
            List<LabSubClassVO> labSubClassVOS1 = subjectService.querySubClassesByIds(collect.toArray(new Long[collect.size()]));
            Map<Long, LabSubClassVO> collect1 = Optional.ofNullable(labSubClassVOS1).orElseGet(Collections::emptyList).stream().collect(Collectors.toMap(LabSubClassVO::getSubjectId, Function.identity()));

            //地址
            List<SubAddrr> subAddrrs = subjectLayoutService.selectAddrrByLayoutIds(layoutids.toArray(new Long[layoutids.size()]));
            Map<Long, SubAddrr> subAddrrMap = Optional.ofNullable(subAddrrs).orElseGet(Collections::emptyList).stream().collect(Collectors.toMap(SubAddrr::getId, Function.identity()));

            //可控设备
            List<LabHardware> labHardwares = hardwareMapper.selectLabHardwareBySubIds(collect.toArray(new Long[collect.size()]));
            Map<Long, List<HardwareCVO>> listHardwareCVOMap = Optional.ofNullable(labHardwares).orElseGet(Collections::emptyList).stream()
                    .filter(a-> HardwareTypeEnum.AI_VENTILATION.equals(a.getType())||HardwareTypeEnum.SWITCH.equals(a.getType()))
                    .map(a ->
                    {
                        HardwareCVO hardware = labSubjectManagerService.getHardwareCVO(a);
                        return hardware;
                    })
                    .collect(Collectors.groupingBy(HardwareCVO::getSubId));


            Optional.ofNullable(temp)
                    .filter(a -> a.size() > 0)
                    .orElseGet(Collections::emptyMap)
                    .entrySet()
                    .forEach(a->{
                        LabSubjectDetailVO value = a.getValue();
                        value.setAddress(Optional.ofNullable(subAddrrMap.get(value.getLayoutId()))
                                .map(SubAddrr::addrrPlus)
                                .orElseGet(()->null));
                        value.setSubClassVO(Optional.ofNullable(collect1.get(value.getId()))
                                .orElseGet(()->null));
                        value.setLabHardwareVOList(listHardwareCVOMap.get(value.getId()));
                    });

        }


        //增加传感器测点信息 杨森说不显示了所以注释掉
//        Map<Long,LabSubjectDetailVO> temp = new HashMap<>();
//        List<Long> collect = Optional.ofNullable(allMap)
//                .filter(a -> a.size() > 0)
//                .orElseGet(Collections::emptyList)
//                .stream()
//                .flatMap(a -> Optional.ofNullable(a.getLayouts())
//                            .filter(c -> c.size() > 0)
//                            .orElseGet(Collections::emptyList)
//                            .stream()
//                            .filter(c -> c.getSubjectDetail() != null)
//                            .filter(c -> c.getSubjectDetail().getId() != null)
//                            .map(c -> {
//                                        //缓存当前对象,减少循环
//                                        temp.put(c.getSubjectDetail().getId(),c.getSubjectDetail());
//                                      return   c.getSubjectDetail().getId();
//                                    })
//                )
//                .distinct()
//                .collect(Collectors.toList());
//
//        if(CollUtil.isNotEmpty(collect))
//        {
//
//            //2.获取传感器
//            List<LabSensor> labSensors = sensorMapper.selectSensorBySubIds(collect.toArray(new Long[collect.size()]));
//            Optional.ofNullable(labSensors)
//                    .filter(a -> a.size() > 0)
//                    .orElseGet(Collections::emptyList)
//                    .stream()
//                    .collect(Collectors.groupingBy(LabSensor::getSubjectId))
//                    .entrySet()
//                    .forEach(a->{
//                        List<SensorFunctionStatus> sensorFunctionStatuses = labSubjectManagerService.getSensorFunctionStatuses(a.getValue());
//                        temp.get(a.getKey()).setSensorFunctionStatuses(Optional.ofNullable(sensorFunctionStatuses).orElseGet(Collections::emptyList));
//                    });
//        }



        return AjaxResult.success(allMap);
    }


    @GetMapping("/getVideoByDeptFloor")
    @ApiOperation(value = "根据组织架构和楼层查询摄像头")
    public AjaxResult getVideoByDeptFloor(@RequestParam String deptId,@RequestParam String type) {
        List<Map<String,Object>> mapList=hardwareMapper.getLabHardwareByDeptFloor(deptId,type);
        return AjaxResult.success(mapList);
    }
    }
