package com.yuchen.saas.park.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yuchen.saas.park.api.entity.park.PmgBatParkBuildingInfo;
import com.yuchen.saas.park.api.entity.park.PmgBatParkFloorInfo;
import com.yuchen.saas.park.api.entity.park.PmgBatParkRoomInfo;
import com.yuchen.saas.park.api.entity.park.PmgLogVideoEventsCount;
import com.yuchen.saas.park.api.vo.park.AbnormalListVO;
import com.yuchen.saas.park.api.vo.park.GetEnvironmentInfo;
import com.yuchen.saas.park.api.vo.park.HandleStatisticsVo;
import com.yuchen.saas.park.api.vo.park.PmgEquipmentPointVo;
import com.yuchen.saas.park.service.mapper.PmgLogVideoEventsCountMapper;
import com.yuchen.saas.park.service.service.*;
import com.yuchen.saas.park.service.util.EnergyDateUtils;
import com.yuchen.saas.park.service.util.WsDateUtil;
import org.apache.commons.lang.StringUtils;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.Condition;
import org.nest.springwrap.core.mp.support.Query;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 张逸飞
 * @create 2021年2月1日 18:51:41
 */
@Service
public class PmgLogVideoEventsCountServiceImpl extends BaseServiceImpl<PmgLogVideoEventsCountMapper, PmgLogVideoEventsCount> implements PmgLogVideoEventsCountService {

    @Resource
    PmgBatParkBuildingInfoService buildingInfoService;

    @Resource
    PmgBatParkFloorInfoService floorInfoService;

    @Resource
    PmgBatParkRoomInfoService roomInfoService;

    @Resource
    PmgBatPointLocationInfoService locationInfoService;
    /**
     * 获取未处理的事件列表
     * @return
     */
    @Override
    public List<PmgLogVideoEventsCount> getNoProcessingList() {
        // 封装条件
        QueryWrapper<PmgLogVideoEventsCount> queryWrapper=new QueryWrapper();
        queryWrapper.eq("is_handling",0);
        queryWrapper.orderByDesc("create_time");
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 获取24小时行为预警趋势
     * @return
     */
    @Override
    public Map<String, Object> getCountTime24() {
        // 得到结果
        List<Map<String, Object>> resultList = baseMapper.getCountTime24();
        List<String> countArr = new ArrayList<String>();
        List<String> timeArr = new ArrayList<String>();
        for(Map map: resultList) {
            timeArr.add(map.get("HOUR").toString());
            countArr.add(map.get("COUNT").toString());
        }
        Map<String,Object> returnMap = new HashMap<>(2);
        returnMap.put("countArr", countArr);
        returnMap.put("timeArr", timeArr);
        return returnMap;
    }

    @Override
    public Map<String, Object> getCountTime24(Long parkId, Long buildingId, Long floorId, Long roomId) {
        // 得到结果
        List<Map<String, Object>> resultList = baseMapper.getCountTime24ByParkId(parkId, buildingId, floorId, roomId);
        List<String> countArr = new ArrayList<String>();
        List<String> timeArr = new ArrayList<String>();
        for(Map map: resultList) {
            timeArr.add(map.get("HOUR").toString());
            countArr.add(map.get("COUNT").toString());
        }
        Map<String,Object> returnMap = new HashMap<>(2);
        returnMap.put("countArr", countArr);
        returnMap.put("timeArr", timeArr);
        return returnMap;
    }

    /**
     * 处理行为异常事件
     * @param id ID
     * @param handlerName 处理人
     * @return
     */
    @Override
    public Integer handlingWarnings(String id, String handlerName) {
        PmgLogVideoEventsCount pmgLogVideoEventsCount = new PmgLogVideoEventsCount();
        pmgLogVideoEventsCount.setId(Long.valueOf(id));
        pmgLogVideoEventsCount.setHandlerName(handlerName);
        pmgLogVideoEventsCount.setHandlerTime(new Date());
        return baseMapper.updateById(pmgLogVideoEventsCount);
    }

    /**
     * 获取总数、已处理、未处理数量
     * @return
     */
    @Override
    public HandleStatisticsVo getStatistics() {
        return baseMapper.getStatistics();
    }

    @Override
    public HandleStatisticsVo getStatistics(String parkId) {
        return baseMapper.getStatisticsByParkId(parkId);
    }

    @Override
    public List<GetEnvironmentInfo> getHourSecurityAbnormalToday(Long parkId, Long buildingId, Long floorId) {
        //获取今日日期
        String dateToday = EnergyDateUtils.getDateToday();
        //获取安防所有设备productName
        List<String> productNameList = locationInfoService.getProductNameList(parkId, buildingId, floorId, null,"6");
        //获取今日异常行为趋势(小时-例折线图)
        List<GetEnvironmentInfo> list = new ArrayList<>();
        if (Func.isNotEmpty(productNameList)) {
            list = baseMapper.getHourSecurityAbnormalDay(productNameList, dateToday);
        }

        //获取今日几点
        int nowHour = EnergyDateUtils.getHourOfToday();
        //没有的小时给0
        for (int i = 1; i <= nowHour + 1; i++) {
            String hourNum = String.valueOf(i);
            if (!list.stream().anyMatch(e -> hourNum.equals(e.getKey()))) {
                GetEnvironmentInfo info = new GetEnvironmentInfo();
                info.setKey(hourNum);
                info.setValue("0");
                list.add(info);
            }
        }
        //升序排序
        list.sort((a, b) -> Integer.parseInt(a.getKey()) - Integer.parseInt(b.getKey()));
        return list;
    }

    @Override
    public List<GetEnvironmentInfo> getDaySecurityAbnormalMonth(Long parkId, Long buildingId, Long floorId) {
        //获取本月日期
        String dateMonth = EnergyDateUtils.getDateMonth();
        //获取安防所有设备productName
        List<String> productNameList = locationInfoService.getProductNameList(parkId, buildingId, floorId, null,"6");
        //获取本月异常行为趋势(天-小时折线图)
        List<GetEnvironmentInfo> list = new ArrayList<>();
        if (Func.isNotEmpty(productNameList)) {
            list = baseMapper.getDaySecurityAbnormalMonth(productNameList, dateMonth);
        }
        //获取今日几号
        int nowDay = WsDateUtil.getDayOfCurrentMonth();
        //获取本月1号日期
        String beginDateMonth = WsDateUtil.getBeginDateOfMonth(0);
        for(int i = 0; i < nowDay; i++) {
            String offsetDate = WsDateUtil.offsetDay(beginDateMonth, i);
            if (!list.stream().anyMatch(e -> offsetDate.equals(e.getKey()))) {
                GetEnvironmentInfo info = new GetEnvironmentInfo();
                info.setKey(offsetDate);
                info.setValue("0");
                list.add(info);
            }
        }
        //升序排序
        list.sort((a, b) -> cn.hutool.core.date.DateUtil
                .parse(a.getKey()).compareTo(cn.hutool.core.date.DateUtil.parse(b.getKey())));
        return list;
    }

    @Override
    public Map<String, List<GetEnvironmentInfo>> getSecurityAbnormalDistribution(Long parkId, Long buildingId, Long floorId) {

        Map<String, List<GetEnvironmentInfo>> rspMap = new HashMap<>();
        List<GetEnvironmentInfo> listToday = new ArrayList<>();
        List<GetEnvironmentInfo> listMonth = new ArrayList<>();
        //获取今日日期
        String dateToday = EnergyDateUtils.getDateToday();
        //获取本月日期
        String dateMonth = EnergyDateUtils.getDateMonth();
        //获取所有点位设备
        List<PmgEquipmentPointVo> equipmentPointList = locationInfoService.selectByAllEquipmentPoint(parkId, buildingId
                , floorId, null);
        //过滤安防的所有设备
        List<PmgEquipmentPointVo> newEquipmentPointList =
                equipmentPointList.stream().filter(e -> "6".equals(e.getCategoryCode())).collect(Collectors.toList());
        //园区场景:查询楼栋分布
        if (Func.isNotEmpty(parkId) && Func.isEmpty(buildingId) && Func.isEmpty(floorId)) {
            LambdaQueryWrapper<PmgBatParkBuildingInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(PmgBatParkBuildingInfo::getParkId, parkId);
            List<PmgBatParkBuildingInfo> buildingList = buildingInfoService.list(lambdaQueryWrapper);
            //循环获取楼栋的异常行为数
            for(PmgBatParkBuildingInfo buildingInfo : buildingList) {
                Long id = buildingInfo.getId();
                String name = buildingInfo.getBuildingName();
                //获取该楼栋所有设备productName
                List<String> pList =
                        newEquipmentPointList.stream().filter(p -> id.equals(p.getBuildingId())).map(PmgEquipmentPointVo::getDeviceName).collect(
                                Collectors.toList());
                addInfoToList(name, pList, listToday, listMonth);
            }
        }
        //楼栋场景:查询楼层分布
        if (Func.isNotEmpty(parkId) && Func.isNotEmpty(buildingId) && Func.isEmpty(floorId)) {
            LambdaQueryWrapper<PmgBatParkFloorInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(PmgBatParkFloorInfo::getBuildingId, buildingId);
            List<PmgBatParkFloorInfo> floorList = floorInfoService.list(lambdaQueryWrapper);
            //循环获取楼层的异常行为数
            for(PmgBatParkFloorInfo floorInfo : floorList) {
                Long id = floorInfo.getId();
                String name = floorInfo.getFloorName();
                //获取该楼栋所有设备productName
                List<String> pList =
                        newEquipmentPointList.stream().filter(p -> id.equals(p.getFloorId())).map(PmgEquipmentPointVo::getDeviceName).collect(
                                Collectors.toList());
                addInfoToList(name, pList, listToday, listMonth);
            }
        }
        //楼层场景:查询房间分布
        if (Func.isNotEmpty(parkId) && Func.isNotEmpty(buildingId) && Func.isNotEmpty(floorId)) {

            LambdaQueryWrapper<PmgBatParkRoomInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(PmgBatParkRoomInfo::getFloorId, floorId);
            List<PmgBatParkRoomInfo> roomList = roomInfoService.list(lambdaQueryWrapper);
            //循环获取楼层的异常行为数
            for(PmgBatParkRoomInfo roomInfo : roomList) {
                Long id = roomInfo.getId();
                String name = roomInfo.getRoomName();
                //获取该楼栋所有设备productName
                List<String> pList =
                        newEquipmentPointList.stream().filter(p -> id.equals(p.getRoomId())).map(PmgEquipmentPointVo::getDeviceName).collect(
                                Collectors.toList());
                addInfoToList(name, pList, listToday, listMonth);
            }
        }
        //今日的异常行为分布
        rspMap.put("distributionToday", listToday);
        //本月的异常行为分布
        rspMap.put("distributionMonth", listMonth);
        return rspMap;
    }

    private void addInfoToList(String key, List<String> productNameList, List<GetEnvironmentInfo> listToday,
                               List<GetEnvironmentInfo> listMonth) {

        int countDay = 0;
        int countMonth = 0;
        if (Func.isNotEmpty(productNameList)) {
            //获取该楼栋今日的异常行为数
            LambdaQueryWrapper<PmgLogVideoEventsCount> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(PmgLogVideoEventsCount::getDeviceName, productNameList);
            queryWrapper.between(PmgLogVideoEventsCount::getTimeStamp,
                    WsDateUtil.getBeginTimeMillisDay(System.currentTimeMillis(), 0),
                    WsDateUtil.getEndTimeMillisDay(System.currentTimeMillis(), 0));
            countDay = this.list(queryWrapper).size();

            countMonth =
                    this.list(new LambdaQueryWrapper<PmgLogVideoEventsCount>()
                            .in(PmgLogVideoEventsCount::getDeviceName, productNameList)
                            .between(PmgLogVideoEventsCount::getTimeStamp,
                                    WsDateUtil.getBeginTimeMillisMonth(System.currentTimeMillis(), 0),
                                    WsDateUtil.getEndTimeMillisMonth(System.currentTimeMillis(), 0))).size();
        }
        //今日统计数据添加到集合
        GetEnvironmentInfo info = new GetEnvironmentInfo();
        info.setKey(key);
        info.setValue(String.valueOf(countDay));
        listToday.add(info);
        //本月统计数据添加到集合
        GetEnvironmentInfo info1 = new GetEnvironmentInfo();
        info1.setKey(key);
        info1.setValue(String.valueOf(countMonth));
        listMonth.add(info1);
    }

    @Override
    public List<AbnormalListVO> getAbnormalList(String categoryCode, Long parkId, Long buildingId, Long floorId) {

        List<AbnormalListVO> abnormalList = new ArrayList<>();
        //获取安防所有设备productName
        List<String> productNameList = locationInfoService.getProductNameList(parkId, buildingId, floorId, null,categoryCode);
        if (Func.isNotEmpty(productNameList)) {
            abnormalList = baseMapper.getAbnormalList(productNameList);
        }
        return abnormalList;
    }

    @Override
    public IPage<PmgLogVideoEventsCount> getListAbnormalBehavior(PmgLogVideoEventsCount pmgLogVideoEventsCount, Query query) {

        LambdaQueryWrapper<PmgLogVideoEventsCount> lambdaWrapper = Wrappers.lambdaQuery();
        IPage<PmgLogVideoEventsCount> pages = this.page(Condition.getPage(query),
                lambdaWrapper.eq(PmgLogVideoEventsCount::getParkId, pmgLogVideoEventsCount.getParkId())
                        .like(StringUtils.isNotBlank(pmgLogVideoEventsCount.getEquipmentName()),
                                PmgLogVideoEventsCount::getEquipmentName, pmgLogVideoEventsCount.getEquipmentName())
                        .le(PmgLogVideoEventsCount::getTimeStamp, cn.hutool.core.date.DateUtil.endOfDay(
                                    cn.hutool.core.date.DateUtil.date()).getTime())
                        .ge(PmgLogVideoEventsCount::getTimeStamp, cn.hutool.core.date.DateUtil
                        .beginOfDay(cn.hutool.core.date.DateUtil.date()).getTime()).orderByDesc(PmgLogVideoEventsCount::getTimeStamp));
        return pages;
    }
}
