/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package com.unis.equipmentOnlineRateAssessment.modular.monitorCamera.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unis.basic.info.modular.orgInfo.entity.OrgInfo;
import com.unis.basic.info.modular.orgInfo.mapper.OrgInfoMapper;
import com.unis.equipmentOnlineRateAssessment.modular.monitorCamera.param.*;
import com.unis.equipmentOnlineRateAssessment.modular.monitorCamera.vo.*;
import com.unis.equipmentOnlineRateAssessment.modular.monitorNvr.entity.MonitorNvr;
import com.unis.equipmentOnlineRateAssessment.modular.monitorNvr.mapper.MonitorNvrMapper;
import com.unis.intelligentManagement.modular.lqdatalayer.entity.TLqDataLayer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.unis.common.exception.CommonException;
import com.unis.equipmentOnlineRateAssessment.modular.monitorCamera.entity.MonitorCamera;
import com.unis.equipmentOnlineRateAssessment.modular.monitorCamera.mapper.MonitorCameraMapper;
import com.unis.equipmentOnlineRateAssessment.modular.monitorCamera.service.MonitorCameraService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.*;
import java.util.*;

/**
 * 摄像头基本信息表Service接口实现类
 *
 * @author hjc
 * @date 2024/06/21 10:07
 **/
@Service
public class MonitorCameraServiceImpl extends ServiceImpl<MonitorCameraMapper, MonitorCamera> implements MonitorCameraService {

    @Autowired
    private OrgInfoMapper orgInfoMapper;

    @Autowired
    private MonitorCameraMapper monitorCameraMapper;

    @Autowired
    private MonitorNvrMapper monitorNvrMapper;


    @Override
    public Page<CameraAndNvrVO> page(MonitorCameraPageParam pageParam) {

        Page<CameraAndNvrVO> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());

        switch (pageParam.getVariety() == null ? 3 : pageParam.getVariety()) {
            case 1:
                page = findCamera(page, pageParam);
                break;
            case 2:
                page = findNvr(pageParam, page);
                break;
            default:
                page = findAll(pageParam, page);

        }
        return page;

    }

    private Page<CameraAndNvrVO> findAll(MonitorCameraPageParam pageParam, Page<CameraAndNvrVO> page) {
        List<MonitorCamera> monitorCameras = monitorCameraMapper.selectList(null);
        List<MonitorNvr> monitorNvrs = monitorNvrMapper.selectList(null);
        List<CameraAndNvrVO> cameraAndNvrVOS = new ArrayList<>();

        for (MonitorCamera monitorCamera : monitorCameras) {
            CameraAndNvrVO vo = new CameraAndNvrVO();
            BeanUtil.copyProperties(monitorCamera, vo);
            vo.setVariety(1);
            cameraAndNvrVOS.add(vo);
        }
        for (MonitorNvr monitorNvr : monitorNvrs) {
            CameraAndNvrVO vo = new CameraAndNvrVO();
            BeanUtil.copyProperties(monitorNvr, vo);
            vo.setVariety(2);
            cameraAndNvrVOS.add(vo);
        }
        page.setRecords(cameraAndNvrVOS.subList(Math.min((pageParam.getCurrent() - 1) * pageParam.getSize(), cameraAndNvrVOS.size())
                , Math.min(pageParam.getCurrent() * pageParam.getSize(), cameraAndNvrVOS.size())));
        page.setTotal(cameraAndNvrVOS.size());
        return page;
    }

    private Page<CameraAndNvrVO> findNvr(MonitorCameraPageParam pageParam, Page<CameraAndNvrVO> list) {
        list = monitorNvrMapper.findNvr(list, pageParam.getName());
        List<CameraAndNvrVO> records = list.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            for (CameraAndNvrVO CameraAndNvrVO : records) {
                CameraAndNvrVO.setVariety(2);
            }
        }

        return list;
    }


    private Page<CameraAndNvrVO> findCamera(Page<CameraAndNvrVO> list, MonitorCameraPageParam pageParam) {
        list = monitorCameraMapper.findcamera(list, pageParam.getName());
        List<CameraAndNvrVO> records = list.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            for (CameraAndNvrVO monitorCamera : records) {
                monitorCamera.setVariety(1);
            }
        }
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(MonitorCameraAddParam monitorCameraAddParam) {
        MonitorCamera monitorCamera = BeanUtil.toBean(monitorCameraAddParam, MonitorCamera.class);
        this.save(monitorCamera);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(MonitorCameraEditParam monitorCameraEditParam) {
        MonitorCamera monitorCamera = this.queryEntity(monitorCameraEditParam.getId());
        BeanUtil.copyProperties(monitorCameraEditParam, monitorCamera);
        this.updateById(monitorCamera);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<MonitorCameraIdParam> monitorCameraIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(monitorCameraIdParamList, MonitorCameraIdParam::getId));
    }

    @Override
    public CameraAndNvrDetailVO detail(MonitorCameraDetailParam detailParam) {

        CameraAndNvrDetailVO vo = new CameraAndNvrDetailVO();
        if (detailParam.getVariety() == 1) {
            //摄像头
            MonitorCamera monitorCamera = this.queryEntity(detailParam.getId());
            BeanUtil.copyProperties(monitorCamera, vo);
            vo.setVariety(1);

        } else if (detailParam.getVariety() == 2) {
            //NVR
            MonitorNvr monitorNvr = monitorNvrMapper.selectById(detailParam.getId());
            BeanUtil.copyProperties(monitorNvr, vo);
            vo.setModelNumber(monitorNvr.getModelNum());
            vo.setSubnetmask(monitorNvr.getSubnetMask());
            vo.setVariety(2);
        }

        return vo;
    }

    @Override
    public MonitorCamera queryEntity(Integer id) {
        MonitorCamera monitorCamera = this.getById(id);
        if (ObjectUtil.isEmpty(monitorCamera)) {
            throw new CommonException("摄像头基本信息表不存在，id值为：{}", id);
        }
        return monitorCamera;
    }


    /**
     * 在线统计分析-分页
     *
     * @author hjc
     * @date 2024/06/21 10:07
     */
    @Override
    public Page<StatisticalAnalysisPageVO> statisticalAnalysisPage(StatisticalAnalysisPageParam pageParam) {

        Page<StatisticalAnalysisPageVO> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());
        return orgInfoMapper.statisticalAnalysisPage(page, pageParam.getZcdzCityName());

    }


    /**
     * 在线统计分析-导出
     *
     * @author hjc
     * @date 2024/06/21 10:07
     */
    @Override
    public void statisticalAnalysisExport(String fileName, HttpServletResponse response) {

        try {
            if (StringUtils.isEmpty(fileName))
                fileName = LocalDate.now().toString();
            fileName = URLEncoder.encode(fileName, "UTF-8");
            // 设置响应信息，让浏览器下载文件
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ExcelTypeEnum.XLSX.getValue());
            EasyExcel.write(response.getOutputStream()) // 或, GrainTempExcel.class
                    .head(StatisticalAnalysisVO.class) // write 中, GrainTempExcel.class 二选一
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet(fileName)
                    .doWrite(orgInfoMapper.statisticalAnalysis());
        } catch (IOException e) {
            log.error("在线统计分析导出异常：{}", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 在线巡检-分页
     *
     * @author hjc
     * @date 2024/06/21 10:07
     */
    @Override
    public Page<OnlineInspectionPageVO> onlineInspectionPage(OnlineInspectionPageParam pageParam) {


        Page<OnlineInspectionPageVO> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());
        Date minDate = null;
        Date maxDate = null;
        if (ObjectUtil.isNotEmpty(pageParam.getWarnTime())) {
            Date warnTime = pageParam.getWarnTime();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(warnTime.getTime()), ZoneId.systemDefault());

            // 通过LocalDateTime的 with方法设置某天的最小值和最大值！！
            LocalDateTime minDateTime = localDateTime.with(LocalTime.MIN);
            // 格式化日期
            minDate = Date.from(minDateTime.atZone(ZoneId.systemDefault()).toInstant());

            LocalDateTime maxDateTime = localDateTime.with(LocalTime.MAX);
            maxDate = Date.from(maxDateTime.atZone(ZoneId.systemDefault()).toInstant());


        }
        return monitorCameraMapper.onlineInspectionPage(page, pageParam.getZcdzCityName(),
                pageParam.getWarnTime(), maxDate, minDate);

    }

    /*
     *
     * 在线巡检-详情
     *
     * @author hjc
     * @date  2024/06/21 10:07
     */
    @Override
    public MonitorCameraVO onlineInspectionDetail(MonitorCameraIdParam monitorCameraIdParam) {

        MonitorCameraVO vo = new MonitorCameraVO();
        MonitorCamera monitorCamera = this.queryEntity(monitorCameraIdParam.getId());
        BeanUtil.copyProperties(monitorCamera, vo);
        OrgInfo orgInfo = orgInfoMapper.selectById(monitorCamera.getOrgId());
        if (ObjectUtil.isNotEmpty(orgInfo)) {
            vo.setOrgName(orgInfo.getOrgName());
        }
        return vo;
    }

    /**
     * 自动考核-分页
     *
     * @author hjc
     * @date 2024/06/21 10:07
     */
    @Override
    public Page<AutomatedAssessmentsPageVO> AutomatedAssessmentsPage(AutomatedAssessmentsPageParam pageParam) {

        Page<AutomatedAssessmentsPageVO> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());

        AutomatedAssessmentsPageVO vo = new AutomatedAssessmentsPageVO();
        //获取摄像头总数量
        Integer cameraAllNum = monitorCameraMapper.selectAll(pageParam.getOrgId());
        //获取摄像头在线数量
        Integer cameraOnlineNum = monitorCameraMapper.selectCameraOnlineNum(pageParam.getOrgId());
        //获取摄像头离线数量
        Integer cameraOfflineNum = monitorCameraMapper.selectCameraOfflineNum(pageParam.getOrgId());

        //获取摄像头在线率
        BigDecimal cameraOnlineRate = null;
        //获取摄像头离线率
        BigDecimal cameraOfflineRate = null;

        if (cameraAllNum != 0) {

            cameraOnlineRate = BigDecimal.valueOf(cameraOnlineNum)
                    .divide(BigDecimal.valueOf(cameraAllNum), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));

            cameraOfflineRate = BigDecimal.valueOf(cameraOfflineNum)
                    .divide(BigDecimal.valueOf(cameraAllNum), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
        }
        //获取NVR总数量
        Integer nvrAllNum = monitorNvrMapper.selectAllNum(pageParam.getOrgId());

        vo.setCameraAllNum(cameraAllNum);
        vo.setCameraOnlineNum(cameraOnlineNum);
        vo.setCameraOfflineNum(cameraOfflineNum);
        vo.setCameraOnlineRate(cameraOnlineRate);
        vo.setCameraOfflineRate(cameraOfflineRate);
        vo.setNvrAllNum(nvrAllNum);

        ArrayList<AutomatedAssessmentsPageVO> list = new ArrayList<>();
        list.add(vo);

        page.setRecords(list);
        page.setTotal(list.size());

        return page;

    }

    /**
     * 自动考核-导出
     *
     * @author hjc
     * @date 2024/06/21 10:07
     */
    @Override
    public void AutomatedAssessmentsExport(AutomatedAssessmentsExportParam param , HttpServletRequest request, HttpServletResponse response) {
        try {
            String fileName = param.getFileName();
            if (StringUtils.isEmpty(fileName));
            fileName = LocalDate.now().toString();
            fileName = URLEncoder.encode(fileName, "UTF-8");
            // 设置响应信息，让浏览器下载文件
            response.setContentType("application/xml");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ExcelTypeEnum.XLSX.getValue());

            EasyExcel.write(response.getOutputStream()) // 或, GrainTempExcel.class
                    .head(AutomatedAssessmentsExportVO.class) // write 中, GrainTempExcel.class 二选一
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet(fileName)
                    .doWrite(this.getData(param));

        } catch (IOException e) {
            log.error("自动考核导出异常：{}", e);
            throw new RuntimeException(e);
        }

    }


    @Override
    public List<MonitorCamera> getlistByOrgId(Integer orgId) {
        QueryWrapper<MonitorCamera> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("org_id",orgId);
        return this.list(queryWrapper);
    }

    @Override
    public Map<String, Object> getCameraNumber(Integer orgId) {
        Map<String, Object> returnMap = new HashMap<>();
        QueryWrapper<MonitorCamera> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("org_id",orgId);
        queryWrapper.eq("isremove",1);//未删除
        List<MonitorCamera> allList = this.list(queryWrapper);
        returnMap.put("zongshuliang",allList.size());

        QueryWrapper<MonitorCamera> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("org_id",orgId);
        queryWrapper1.eq("isremove",1);//未删除
        queryWrapper1.eq("status",1);//在线
        List<MonitorCamera> zxList = this.list(queryWrapper1);
        returnMap.put("zaix",zxList.size());

        QueryWrapper<MonitorCamera> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("org_id",orgId);
        queryWrapper2.eq("isremove",1);//未删除
        queryWrapper2.eq("status",2);//离线
        List<MonitorCamera> lxList = this.list(queryWrapper2);
        returnMap.put("lix",lxList.size());
        return returnMap;
    }


    private List<AutomatedAssessmentsExportVO> getData(AutomatedAssessmentsExportParam param){
        AutomatedAssessmentsExportVO vo = new AutomatedAssessmentsExportVO();
        List<AutomatedAssessmentsExportVO> list = new ArrayList<>();
        BeanUtil.copyProperties(param,vo);
        list.add(vo);

        return list;
    }


/*    private List<AutomatedAssessmentsExportVO> data() {
        AutomatedAssessmentsExportVO vo = new AutomatedAssessmentsExportVO();
        //获取摄像头总数量
        Integer cameraAllNum = monitorCameraMapper.selectAll(null);
        //获取摄像头在线数量
        Integer cameraOnlineNum = monitorCameraMapper.selectCameraOnlineNum(null);
        //获取摄像头离线数量
        Integer cameraOfflineNum = monitorCameraMapper.selectCameraOfflineNum(null);
        //获取摄像头在线率
        BigDecimal cameraOnlineRate = null;
        //获取摄像头离线率
        BigDecimal cameraOfflineRate = null;

        if (cameraAllNum != 0) {

            cameraOnlineRate = BigDecimal.valueOf(cameraOnlineNum)
                    .divide(BigDecimal.valueOf(cameraAllNum), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));

            cameraOfflineRate = BigDecimal.valueOf(cameraOfflineNum)
                    .divide(BigDecimal.valueOf(cameraAllNum), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));

        }
        //获取NVR总数量
        Integer nvrAllNum = monitorNvrMapper.selectAllNum(null);

        vo.setCameraAllNum(cameraAllNum);
        vo.setCameraOnlineNum(cameraOnlineNum);
        vo.setCameraOfflineNum(cameraOfflineNum);
        vo.setCameraOnlineRate(cameraOnlineRate);
        vo.setCameraOfflineRate(cameraOfflineRate);
        vo.setNvrAllNum(nvrAllNum);

        List<AutomatedAssessmentsExportVO> list = new ArrayList<>();
        list.add(vo);

        return list;
    }*/

}
