/*
 *
 *  * | Licensed 未经许可不能去掉「OPENIITA」相关版权
 *  * +----------------------------------------------------------------------
 *  * | Author: xw2sy@163.com
 *  * +----------------------------------------------------------------------
 *
 *  Copyright [2024] [OPENIITA]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * /
 */
package cc.iotkit.manager.controller;

import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.satoken.utils.AuthUtil;
import cc.iotkit.data.config.TenantContext;
import cc.iotkit.data.manager.IAlertRecordData;
import cc.iotkit.data.manager.ICategoryData;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.data.manager.IProductData;
import cc.iotkit.manager.dto.bo.device.DeviceQueryBo;
import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo;
import cc.iotkit.manager.model.stats.MainStats;
import cc.iotkit.manager.service.AlertService;
import cc.iotkit.manager.service.IDeviceManagerService;
import cc.iotkit.model.alert.AlertRecord;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.stats.AlertStatDTO;
import cc.iotkit.temporal.IThingModelMessageData;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = {"状态"})
@Slf4j
@RestController
@RequestMapping("/stats")
public class StatsController {

    @Autowired
    private ICategoryData ICategoryData;
    @Autowired
    @Qualifier("productDataCache")
    private IProductData productData;
    @Autowired
    @Qualifier("deviceInfoDataCache")
    private IDeviceInfoData deviceInfoData;
    @Autowired
    private IThingModelMessageData thingModelMessageData;
    @Autowired
    private IAlertRecordData iAlertRecordData;
    @Autowired
    private AlertService alertService;
    @Autowired
    private IDeviceManagerService deviceServiceImpl;
    @PostMapping("/main")
    public MainStats getMainStats() {
        MainStats mainStats = new MainStats();
        String uid = AuthUtil.getUserId();
        log.info("Thread {} - TenantFilter disabled: {}",
                Thread.currentThread().getId(),
                TenantContext.isFilterDisabled());
        long now = System.currentTimeMillis();
        if (AuthUtil.isAdmin()) {
            mainStats.setCategoryTotal(ICategoryData.count());
            mainStats.setProductTotal(productData.count());
            mainStats.setDeviceTotal(deviceInfoData.count());

            DeviceInfo condition = new DeviceInfo();
            DeviceInfo.State state = new DeviceInfo.State();
            state.setOnline(true);
            condition.setState(state);
            mainStats.setOnlineTotal(deviceInfoData.findAllByCondition(condition).size());

            state.setOnline(false);
            condition.setState(state);
            mainStats.setOfflineTotal(deviceInfoData.findAllByCondition(condition).size());

            // 待激活设备
            mainStats.setNeverOnlineTotal(deviceInfoData.findNeverUsedDevices().size());

            mainStats.setReportTotal(thingModelMessageData.count());
            //上行数据统计
            mainStats.setDeviceUpMessageStats(thingModelMessageData.getDeviceUpMessageStatsWithUid(null, null, null));
            // 下行数据统计
            mainStats.setDeviceDownMessageStats(thingModelMessageData.getDeviceDownMessageStatsWithUid(null, null, null));
            //产品数量统计
            mainStats.setDeviceStatsOfCategory(deviceInfoData.getDeviceStatsByCategory(""));
        } else {
            mainStats.setCategoryTotal(ICategoryData.count());
//            mainStats.setProductTotal(productData.countByUid(uid));
            mainStats.setDeviceTotal(deviceInfoData.countByUid(uid));
//            mainStats.setReportTotal(deviceReportRepository.countByUid(uid));
            //上报数据统计
            mainStats.setReportDataStats(thingModelMessageData.getDeviceMessageStatsWithUid(uid, now - 48 * 3600 * 1000, now));
            //产品数量统计
            mainStats.setDeviceStatsOfCategory(deviceInfoData.getDeviceStatsByCategory(uid));
        }

        return mainStats;
    }


    @PostMapping("/mainAlertRecord")
    public String getAlertRecord() {
        List<AlertStatDTO>  list = iAlertRecordData.getAlertRecord();
      //  jpaQueryFactory
       // iAlertRecordData.findAll();
        return  JSONUtil.toJsonPrettyStr(list);
      //  return list;
    }
    @PostMapping("/deviceRecord")
    public String getDeviceRecord() {
        List<AlertStatDTO>  list = deviceInfoData.getDeviceRecord();
        //  jpaQueryFactory
        // iAlertRecordData.findAll();
        return  JSONUtil.toJsonPrettyStr(list);
        //  return list;
    }
    @PostMapping("/mainTop")
    public String getMainTop() {
        //过滤租户开启

        TenantContext.disableTenantFilter();
        log.info("Thread {} - TenantFilter disabled: {}",
                Thread.currentThread().getId(),
                TenantContext.isFilterDisabled());

        MainStats mainStats = new MainStats();
        String uid = AuthUtil.getUserId();
        mainStats.setCategoryTotal(ICategoryData.count());
        mainStats.setProductTotal(productData.count());
        mainStats.setDeviceTotal(deviceInfoData.count());

        DeviceInfo condition = new DeviceInfo();
        DeviceInfo.State state = new DeviceInfo.State();
        state.setOnline(true);
        condition.setState(state);
        mainStats.setOnlineTotal(deviceInfoData.findAllByCondition(condition).size());

        state.setOnline(false);
        condition.setState(state);
        mainStats.setOfflineTotal(deviceInfoData.findAllByCondition(condition).size());

        // 待激活设备
        mainStats.setNeverOnlineTotal(deviceInfoData.findNeverUsedDevices().size());

        mainStats.setReportTotal(thingModelMessageData.count());
        //上行数据统计
        mainStats.setDeviceUpMessageStats(thingModelMessageData.getDeviceUpMessageStatsWithUid(null, null, null));
        // 下行数据统计
        mainStats.setDeviceDownMessageStats(thingModelMessageData.getDeviceDownMessageStatsWithUid(null, null, null));
        //产品数量统计
        mainStats.setDeviceStatsOfCategory(deviceInfoData.getDeviceStatsByCategory(""));

        //告警总数
        mainStats.setAlertCount(iAlertRecordData.count());
        mainStats.setProductKeyCount(deviceInfoData.getProductDevice(null,null,null));
        //  jpaQueryFactory
        // iAlertRecordData.findAll();
        //过滤租户关
        //TenantContext.enableTenantFilter();
        return  JSONUtil.toJsonPrettyStr(mainStats);
    }
    @PostMapping("/mainListProduct")
    public String mainListProduct(Long deptAreaId,String startDate, String endDate) {
        //过滤租户开启

        TenantContext.disableTenantFilter();
        log.info("Thread {} - TenantFilter disabled: {}",
                Thread.currentThread().getId(),
                TenantContext.isFilterDisabled());

        MainStats mainStats = new MainStats();

        mainStats.setProductKeyCount(deviceInfoData.getProductDevice(deptAreaId,startDate,endDate));
        //  jpaQueryFactory
        // iAlertRecordData.findAll();
        //过滤租户关
        //TenantContext.enableTenantFilter();
        return  JSONUtil.toJsonPrettyStr(mainStats.getProductKeyCount());
    }

    @ApiOperation(value = "设备列表", notes = "设备列表", httpMethod = "POST")
    //@SaCheckPermission("iot:device:query")
    @PostMapping("/list")
    public String getDevices(String productKey,Integer type) {
        List<DeviceInfo> list = new ArrayList<>();
        List<DeviceInfoVo> list1 = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(type) && type==0) {
            PageRequest<DeviceQueryBo> pageRequest = new PageRequest<>(20, 1, null);
            pageRequest.setData(new DeviceQueryBo());
            pageRequest.getData().setProductKey(productKey);
            list1 = deviceServiceImpl.getDevices(pageRequest).getRows();
            for (DeviceInfoVo deviceInfoVo : list1) {
                deviceInfoVo.setOnlineStatus(deviceInfoVo.getOnline()?"在线":"离线");
                deviceInfoVo.setProductName(ObjectUtils.isNotEmpty(deviceInfoVo.getProduct().getName()) ? deviceInfoVo.getProduct().getName():"");
            }
            return  JSONUtil.toJsonPrettyStr(list1);
        }
    /*    for (DeviceInfo deviceInfo : list) {
            deviceInfo.setOnlineStatus(deviceInfo.getOnline()?"在线":"离线");
        }*/
        return  JSONUtil.toJsonPrettyStr(deviceInfoData.findByConditionsList(productKey));
    }
    @ApiOperation("查询告警消息分页")
   // @SaCheckPermission("iot:alert:query")
    @PostMapping("/mainListAlert")
    public String selectAlertRecordList() {
      PageRequest<AlertRecord> request  = new PageRequest<>(20, 1, null);
        request.setData(new AlertRecord());
      /*  DateTimeFormatter formatter =
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("Asia/Shanghai"));
*/
        List<AlertRecord> list = alertService.selectAlertRecordPage(request).getRows();
        for (AlertRecord record : list) {
            String formattedTime = Instant.ofEpochMilli(record.getAlertTime()).atZone(ZoneId.of("Asia/Shanghai"))
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            //String formattedTime = zonedDateTime.format(formatter);
                record.setAlertTimeStats(formattedTime
                );
        }
        return JSONUtil.toJsonPrettyStr(list);
    }
}
