package com.njcn.device.pms.controller.ledgerManger;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.device.biz.pojo.dto.StatisticsMonitor;
import com.njcn.device.biz.pojo.dto.*;
import com.njcn.device.biz.pojo.param.DeptGetLineParam;
import com.njcn.device.biz.pojo.param.MonitorGetParam;
import com.njcn.device.biz.pojo.param.SubstationParam;
import com.njcn.device.biz.pojo.po.Overlimit;
import com.njcn.device.biz.pojo.po.PqsDeviceUnit;
import com.njcn.device.pms.mapper.majornetwork.PqsDeviceUnitMapper;
import com.njcn.device.pms.pojo.param.pwUser.PwUserMonitorParam;
import com.njcn.device.pms.pojo.po.DistributionMonitor;
import com.njcn.device.pms.pojo.po.Monitor;
import com.njcn.device.pms.pojo.po.PmsTerminal;
import com.njcn.device.pms.pojo.vo.pwUser.PwUserMonitorDataVO;
import com.njcn.device.pms.service.ledgerManger.CommTerminalService;
import com.njcn.device.pms.service.majornetwork.IDistributionMonitorService;
import com.njcn.device.pms.service.majornetwork.IMonitorService;
import com.njcn.device.pms.service.majornetwork.ITerminalService;
import com.njcn.device.pq.pojo.vo.PqsDeviceUnitVo;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

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

/**
 * @author wr
 * @description
 * @date 2023/4/26 10:00
 */
@RestController
@RequestMapping("/commTerminal")
@RequiredArgsConstructor
@Slf4j
@Api(tags = "通用台账查询")
public class CommTerminalController extends BaseController {

    private final IMonitorService monitorService;

    private final IDistributionMonitorService iDistributionMonitorService;

    private final CommTerminalService commTerminalService;

    private final ITerminalService terminalService;

    private final PqsDeviceUnitMapper pqsDeviceUnitMapper;


    /**
     * 通过部门获取所有子集部门所拥有的监测点
     *
     * @author wr
     * @date 2023/4/26
     */
    @PostMapping("/deptGetLineIds")
    @ApiOperation("通过部门获取所有子集部门所拥有的监测点")
    @ApiImplicitParam(name = "param", value = "请求参数", required = true)
    public HttpResult<List<DeptGetChildrenDTO>> deptGetLineList(@RequestBody @Validated DeptGetLineParam param) {
        String methodDescribe = getMethodDescribe("deptGetLineList");
        TimeInterval timer = new TimeInterval();
        List<DeptGetChildrenDTO> monitor = monitorService.deptMonitor(param);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, monitor, methodDescribe);
    }





    /**
     * 根据单位获取所有子单位信息
     * @author cdf
     * @date 2023/5/10
     */
    @PostMapping("getDeptChildrenByParent")
    @ApiOperation("根据单位获取所有子单位信息")
    @ApiImplicitParam(name = "deptGetLineParam", value = "请求体", required = true)
    public HttpResult<List<DeptGetBase>> getDeptChildrenByParent(@RequestBody @Validated DeptGetLineParam deptGetLineParam) {
        TimeInterval timer = new TimeInterval();
        String methodDescribe = getMethodDescribe("getDeptChildrenByParent");
        List<DeptGetBase> result = commTerminalService.getDeptChildrenByParent(deptGetLineParam);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    /**
     * 根据单位获取层级单位的监测点信息
     * @author cdf
     * @date 2023/5/10
     */
    @PostMapping("deptGetLine")
    @ApiOperation("根据单位获取监测点信息")
    @ApiImplicitParam(name = "deptGetLineParam", value = "请求体", required = true)
    public HttpResult<List<DeptGetChildrenMoreDTO>> deptGetLine(@RequestBody @Validated DeptGetLineParam deptGetLineParam) {
        TimeInterval timer = new TimeInterval();
        String methodDescribe = getMethodDescribe("deptGetLine");
        List<DeptGetChildrenMoreDTO> result = commTerminalService.deptGetLine(deptGetLineParam);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }




    /**
     * 根据单位获取所有变电站
     * @author cdf
     * @date 2023/5/10
     */
    @PostMapping("deptGetSubStation")
    @ApiOperation("根据单位获取所有变电站")
    @ApiImplicitParam(name = "deptGetLineParam", value = "请求体", required = true)
    public HttpResult<List<DeptGetSubStationDTO>> deptSubStation(@RequestBody @Validated DeptGetLineParam deptGetLineParam) {
        TimeInterval timer = new TimeInterval();
        String methodDescribe = getMethodDescribe("deptSubStation");
        List<DeptGetSubStationDTO> result = commTerminalService.deptSubStation(deptGetLineParam);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    /**
     * 根据单位获取所有变电站详细信息
     * @param deptGetLineParam
     * @return
     */
    @PostMapping("/deptGetSubStationInfo")
    @ApiOperation("根据单位获取所有变电站详细信息")
    @ApiImplicitParam(name = "deptGetLineParam", value = "请求体", required = true)
    public HttpResult<List<DeptGetSubStationDTO.Info>> deptGetSubStationInfo(@RequestBody @Validated DeptGetLineParam deptGetLineParam) {
        String methodDescribe = getMethodDescribe("deptGetSubStationInfo");
        List<DeptGetSubStationDTO.Info> result = commTerminalService.deptSubStationInfo(deptGetLineParam);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }
    /**
     * 根据单位获取所有母线
     * @author cdf
     * @date 2023/5/10
     */
    @PostMapping("deptGetBusBar")
    @ApiOperation("根据单位获取所有母线")
    @ApiImplicitParam(name = "deptGetLineParam", value = "请求体", required = true)
    public HttpResult<List<DeptGetBusBarDTO>> deptBusBar(@RequestBody @Validated DeptGetLineParam deptGetLineParam) {
        TimeInterval timer = new TimeInterval();
        String methodDescribe = getMethodDescribe("deptBusBar");
        List<DeptGetBusBarDTO> result = commTerminalService.deptBusBar(deptGetLineParam);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }



    /**
     * 根据单位获取所有装置
     * @author cdf
     * @date 2023/5/10
     */
    @PostMapping("deptGetDevice")
    @ApiOperation("根据单位获取所有装置")
    @ApiImplicitParam(name = "deptGetLineParam", value = "请求体", required = true)
    public HttpResult<List<DeptGetDeviceDTO>> deptGetDevice(@RequestBody @Validated DeptGetLineParam deptGetLineParam) {
        TimeInterval timer = new TimeInterval();
        String methodDescribe = getMethodDescribe("deptGetDevice");
        List<DeptGetDeviceDTO> result = commTerminalService.deptGetDevice(deptGetLineParam,0);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    /**
     * 根据单位获取单位下的装置以及装置下的监测点
     * @author cdf
     * @date 2023/5/10
     */
    @PostMapping("deptGetDeviceAndMonitor")
    @ApiOperation("根据单位获取装置以及监测点")
    @ApiImplicitParam(name = "deptGetLineParam", value = "请求体", required = true)
    public HttpResult<List<DeptGetDeviceDTO>> deptGetDeviceAndMonitor(@RequestBody @Validated DeptGetLineParam deptGetLineParam) {
        TimeInterval timer = new TimeInterval();
        String methodDescribe = getMethodDescribe("deptGetDeviceAndMonitor");
        List<DeptGetDeviceDTO> result = commTerminalService.deptGetDevice(deptGetLineParam,1);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }


    /**
     * 根据单站id获取监测点信息
     * @author cdf
     * @date 2023/5/10
     */
    @PostMapping("substationGetLine")
    @ApiOperation("根据电站获取所有监测点")
    @ApiImplicitParam(name = "substationId", value = "请求体", required = true)
    public HttpResult<LineDevGetBandDTO> substationGetLine(@RequestParam("substationId")String substationId) {
        TimeInterval timer = new TimeInterval();
        String methodDescribe = getMethodDescribe("substationGetLine");
        LineDevGetBandDTO result = commTerminalService.substationGetLine(substationId);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }


    /**
     * 根据母线id获取监测点信息
     * @author cdf
     * @date 2023/5/10
     */
    @PostMapping("busBarGetLine")
    @ApiOperation("根据母线id获取监测点信息")
    @ApiImplicitParam(name = "busBarId", value = "请求体", required = true)
    public HttpResult<LineDevGetBandDTO> busBarGetLine(@RequestParam("busBarId")String busBarId) {
        TimeInterval timer = new TimeInterval();
        String methodDescribe = getMethodDescribe("busBarGetLine");
        LineDevGetBandDTO result = commTerminalService.busBarGetLine(busBarId);
        log.info("运行时长" + timer.intervalRestart());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }


    /**
     * 重新计算限值
     *
     * @author cdf
     * @date 2022/5/17
     */
    @ApiOperation("监测点-重新计算限值")
    @GetMapping(value = "updatePmsOverLimit")
    public HttpResult<String> updatePmsOverLimit() {
        String methodDescribe = getMethodDescribe("updatePmsOverLimit");
        String count = commTerminalService.updatePmsOverLimit();
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, count, methodDescribe);
    }


    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @PostMapping("/getOverLimitData")
    @ApiOperation("根据监测点id获取越限数值")
    @ApiImplicitParam(name = "id", value = "监测点id", required = true)
    public HttpResult<Overlimit> getOverLimitData(@RequestParam("id") String id) {
        String methodDescribe = getMethodDescribe("getOverLimitData");
        Overlimit result = monitorService.getOverLimitData(id);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @PostMapping("/getOverLimitDataByIds")
    @ApiOperation("根据监测点id集合获取越限数值")
    @ApiImplicitParam(name = "ids", value = "监测点id集合", required = true)
    public HttpResult<List<Overlimit>> getOverLimitDataByIds(@RequestBody List<String> ids) {
        String methodDescribe = getMethodDescribe("getOverLimitDataByIds");
        List<Overlimit> result = monitorService.getOverLimitDataByIds(ids);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @PostMapping("/getAllLineOverLimit")
    @ApiOperation("获取投运在线的监测点的限值")
    public HttpResult<List<Overlimit>> getAllLineOverLimit() {
        String methodDescribe = getMethodDescribe("getAllLineOverLimit");
        List<Overlimit> result = monitorService.getAllLineOverLimit();
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }
    @PostMapping("/getLineBySubstationRelation")
    @ApiOperation("获取变电站和监测点的关系")
    @ApiImplicitParam(name = "devDataType", value = "数据类型（0：暂态系统；1：稳态系统；）", required = true)
    public HttpResult<Map<String,List<String>>> getLineBySubstationRelation(@RequestParam("devDataType") Integer devDataType) {
        String methodDescribe = getMethodDescribe("getLineBySubstationRelation");
        Map<String,List<String>> map= monitorService.getLineBySubstationRelation(0);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, map, methodDescribe);
    }

    /**
     * 获取实际，投运，谐波系统 的监测点
     */
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @GetMapping("/getRunMonitorIds")
    @ApiOperation("获取投运谐波系统所有监测点")
    public HttpResult<List<String>> getRunMonitorIds() {
        String methodDescribe = getMethodDescribe("getRunMonitorIds");
        List<String> result = commTerminalService.getRunMonitorList();
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }


    /**
     * 根据监测点集合获取监测点详情
     * @author cdf
     * @date 2023/9/21
     */
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @PostMapping("/getMonitorDetailList")
    @ApiOperation("根据监测点集合获取监测点详情")
    @ApiImplicitParam(name = "list", value = "监测点集合")
    public HttpResult<List<LineDevGetDTO>> getMonitorDetailList(@RequestBody List<String> list) {
        String methodDescribe = getMethodDescribe("getMonitorDetailList");
        List<LineDevGetDTO> monitorList = monitorService.getPmsCalMonitorList(list);
        //获取设备最新数据时间
        List<String> devList = monitorList.stream().map(LineDevGetDTO::getDevId).distinct().collect(Collectors.toList());
        List<PmsTerminal> terminals = terminalService.getTerminalSelectByIds(devList);
        Map<String,List<PmsTerminal>> map = terminals.stream().collect(Collectors.groupingBy(PmsTerminal::getId));
        monitorList.forEach(item->{
            if (!Objects.isNull(map.get(item.getDevId()))){
                item.setUpdateTime(map.get(item.getDevId()).get(0).getUpdateTime());
            }
        });
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS,monitorList, methodDescribe);
    }

    /**
     * 通过监测点获取监测点数据单位
     * @author cdf
     * @date 2023/9/21
     */
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @GetMapping("/lineUnitDetail")
    @ApiOperation("根据监测点id获取数据单位")
    @ApiImplicitParam(name = "lineId", value = "实体", required = true)
    public HttpResult<PqsDeviceUnit> lineUnitDetail(@RequestParam("lineId") String lineId) {
        String methodDescribe = getMethodDescribe("lineUnitDetail");
        String devId;
        if(lineId.contains("pmswifi_")){

            DistributionMonitor distributionMonitor  = iDistributionMonitorService.getOne(new LambdaQueryWrapper<DistributionMonitor>().eq(DistributionMonitor::getMonitorId,lineId));
            if(Objects.isNull(distributionMonitor)){
                return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, new PqsDeviceUnit(), methodDescribe);
            }
            devId = distributionMonitor.getTerminalId();
        }else {
            Monitor monitor = monitorService.getById(lineId);
            if(Objects.isNull(monitor)){
                return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, new PqsDeviceUnit(), methodDescribe);
            }
            devId = monitor.getTerminalId();
        }
        PqsDeviceUnit pqsDeviceUnit = pqsDeviceUnitMapper.selectById(devId);
        if(Objects.isNull(pqsDeviceUnit)){
            pqsDeviceUnit = new PqsDeviceUnit();
        }
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, pqsDeviceUnit, methodDescribe);
    }


    /**
     * 根据监测点id获取监测点详情
     * @author cdf
     * @date 2023/9/21
     */
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @GetMapping("/getMonitorDetail")
    @ApiOperation("根据监测点id获取监测点详情")
    @ApiImplicitParam(name = "lineId", value = "实体", required = true)
    public HttpResult<LineDevGetDTO> getMonitorDetail(@RequestParam("lineId") String lineId) {
        String methodDescribe = getMethodDescribe("getMonitorDetail");
        LineDevGetDTO lineDevGetDTO = commTerminalService.getMonitorDetail(lineId);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, lineDevGetDTO, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @PostMapping("/getStatisticsMonitor")
    @ApiOperation("专项分析台账统计")
    @ApiImplicitParam(name = "param", value = "实体", required = true)
    public HttpResult<List<StatisticsMonitor>> getStatisticsMonitor(@RequestBody StatisticsBizBaseParam param) {
        String methodDescribe = getMethodDescribe("getStatisticsMonitor");
        List<StatisticsMonitor> statisticsMonitor = commTerminalService.getStatisticsMonitor(param);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, statisticsMonitor, methodDescribe);
    }

    /**
     * 获取监测点的台账详细信息
     * @author cdf
     * @date 2023/10/23
     */
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @GetMapping("/getCustomDetailByLineId")
    @ApiOperation("获取监测点的台账详细信息(自定义报表用)")
    @ApiImplicitParam(name = "id", value = "监测点ID", required = true)
    public HttpResult<Map<String,String>> getCustomDetailByLineId(@RequestParam("id") String id) {
        String methodDescribe = getMethodDescribe("getCustomDetailByLineId");
        Map<String,String> result = commTerminalService.getCustomDetailByLineId(id);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    /**
     * pms获取指定单位下面的母线以及母线下面的监测点信息
     * @author cdf
     * @date 2024/1/26
     */
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @GetMapping("/getBusBarAndHisMonitor")
    @ApiOperation("pms获取指定单位下面的母线以及母线下面的监测点信息")
    public HttpResult<List<BusBarAndHisMonitorDTO>> getBusBarAndHisMonitor() {
        String methodDescribe = getMethodDescribe("getBusBarAndHisMonitor");
        List<BusBarAndHisMonitorDTO> busBarAndHisMonitorDTOList = commTerminalService.getBusBarAndHisMonitor();
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, busBarAndHisMonitorDTOList, methodDescribe);
    }



    /**
     * 根据对象标签，监测点，获取主网监测点
     * @author cdf
     * @date 2024/2/28
     */
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @PostMapping("/tagOrIdGetMonitorList")
    @ApiOperation("根据对象标签，监测点，获取主网监测点")
    public HttpResult<List<CommMonitorInfoDTO>> tagOrIdGetMonitorList(@RequestBody MonitorGetParam monitorGetParam) {
        String methodDescribe = getMethodDescribe("tagOrIdGetMonitorList");
        List<CommMonitorInfoDTO> busBarAndHisMonitorDTOList = commTerminalService.tagOrIdGetMonitorList(monitorGetParam.getTagList(),monitorGetParam.getMonitorIds(),monitorGetParam.getDeptIds());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, busBarAndHisMonitorDTOList, methodDescribe);
    }


    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @PostMapping("/tagOrIdGetSub")
    @ApiOperation("获取变电站信息")
    public HttpResult<List<SubGetBase>> tagOrIdGetSub(@RequestBody SubstationParam substationParam) {
        String methodDescribe = getMethodDescribe("tagOrIdGetSub");
        List<SubGetBase> subGetBases = commTerminalService.tagOrIdGetSub(substationParam);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, subGetBases, methodDescribe);
    }



    /**
     * 用于返回pq 还是pms系统
     * @author cdf
     * @date 2023/8/3
     */
    @GetMapping("isPqOrPms")
    @ApiOperation("用于返回pq 还是pms系统")
    @ApiIgnore
    public HttpResult<String> isPqOrPms() {
        String methodDescribe = getMethodDescribe("isPqOrPms");
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "pms", methodDescribe);
    }









}
