package com.ruoyi.web.controller.system;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.LocationUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.TEarlyWarning;
import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据大屏Controller
 *
 * @author zhengjie
 * @date 2023-09-08
 */
@RestController
@RequestMapping("/system/display")
public class TDataDisplayController extends BaseController {
    @Autowired
    private ITShouhuanAlarmListService tShouhuanAlarmListService;

    @Autowired
    private ITDeviceListService tDeviceListService;

    @Autowired
    private ITShouhuanInfoService itShouhuanInfoService;

    @Autowired
    private ITUserProfileService userProfileService;

    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private ITEarlyWarningService tEarlyWarningService;

    @Autowired
    private LocationUtils locationUtils;

    /**
     * 查询SOS预警处理列表
     */
    @GetMapping("/list")
    public TableDataInfo list(TEarlyWarning earlyWarning) {
        startPage();
        List<TEarlyWarning> tEarlyWarnings = tEarlyWarningService.selectTEarlyWarningList_SOS(earlyWarning);
        return getDataTable(tEarlyWarnings);
    }

    @GetMapping("/count")
    public AjaxResult count() {
        return success(userProfileService.selectuserAgeCount());
    }

    @GetMapping("/alarm")
    public AjaxResult alarm() {
        AlarmStatusDto alarmStatusDto = new AlarmStatusDto();
        /** SOS告警处理 */
        int alarmSOSSolve = tEarlyWarningService.selectTEarlyWarningCompletedCountByType(16);
        alarmStatusDto.setAlarmSOSSolve(alarmSOSSolve);
        /** SOS未告警处理 */
        int un_alarmSOSSolve = tEarlyWarningService.selectTEarlyWarningUnCompletedCountByType(16);
        alarmStatusDto.setUn_alarmSOSSolve(un_alarmSOSSolve);
        /** 围栏告警处理 alarmRailSolve */
//        int alarmRailSolve = tEarlyWarningService.selectTEarlyWarningCompletedCountByType();
        alarmStatusDto.setAlarmRailSolve(0);
        /** 围栏未告警处理 un_alarmRailSolve */
//        int un_alarmRailSolve = tEarlyWarningService.selectTEarlyWarningUnCompletedCountByType();
        alarmStatusDto.setUn_alarmRailSolve(0);
        /** 心率告警处理 */
        int alarmHeartSolve = tEarlyWarningService.selectTEarlyWarningCompletedCountByType(22);
        alarmStatusDto.setAlarmHeartSolve(alarmHeartSolve);
        /** 心率未告警处理 */
        int un_alarmHeartSolve = tEarlyWarningService.selectTEarlyWarningUnCompletedCountByType(22);
        alarmStatusDto.setUn_alarmHeartSolve(un_alarmHeartSolve);
        /** 跌倒告警处理  */
        int alarmFallSolve = tEarlyWarningService.selectTEarlyWarningCompletedCountByType(21);
        alarmStatusDto.setAlarmFallSolve(alarmFallSolve);
        /** 跌倒未告警处理  */
        int un_alarmFallSolve = tEarlyWarningService.selectTEarlyWarningUnCompletedCountByType(21);
        alarmStatusDto.setUn_alarmFallSolve(un_alarmFallSolve);
        /** 低电告警处理 alarmLowSolve */
        int alarmLowSolve = tEarlyWarningService.selectTEarlyWarningCompletedCountByType(17);
        alarmStatusDto.setAlarmLowSolve(alarmLowSolve);
        /** 低电未告警处理 un_alarmLowSolve */
        int un_alarmLowSolve = tEarlyWarningService.selectTEarlyWarningUnCompletedCountByType(17);
        alarmStatusDto.setUn_alarmLowSolve(un_alarmLowSolve);
        /** 设备状态告警处理 alarmStatusSolve */
        int alarmStatusSolve = tEarlyWarningService.selectTEarlyWarningCompletedCountByType(20);
        alarmStatusDto.setAlarmStatusSolve(alarmStatusSolve);
        /** 设备状态未告警处理 un_alarmStatusSolve */
        int un_alarmStatusSolve = tEarlyWarningService.selectTEarlyWarningUnCompletedCountByType(20);
        alarmStatusDto.setUn_alarmStatusSolve(un_alarmStatusSolve);
        return success(alarmStatusDto);
    }

    @GetMapping("/percent")
    public AjaxResult percent() {
        AlarmPercentDto alarmPercentDto = new AlarmPercentDto();
        /** SOS alarmSOS*/
        Double alarmSOS = tEarlyWarningService.selectTEarlyWarningUnCompletedPercentageByType(16);
        alarmPercentDto.setAlarmSOS((alarmSOS == null || alarmSOS.isNaN()) ? "0.00" : alarmSOS.toString());
        /** 围栏 alarmRail*/
//        Double alarmRail = tEarlyWarningService.selectTEarlyWarningUnCompletedPercentageByType();
        alarmPercentDto.setAlarmRail("0.00");
        /** 跌倒 alarmFall*/
        Double alarmFall = tEarlyWarningService.selectTEarlyWarningUnCompletedPercentageByType(21);
        alarmPercentDto.setAlarmFall((alarmFall == null || alarmFall.isNaN()) ? "0.00" : alarmFall.toString());
        /** 在线 alarmStauts*/
        Double alarmStauts = itShouhuanInfoService.selectTShouhuanInfoPercentage();
        alarmPercentDto.setAlarmStauts((alarmStauts == null || alarmStauts.isNaN()) ? "0.00" : alarmStauts.toString());
        /** 全部 alarmAll*/
        Double alarmAll = tEarlyWarningService.selectTEarlyWarningUnCompletedPercentageByAllType();
        alarmPercentDto.setAlarmAll((alarmAll == null || alarmAll.isNaN()) ? "0.00" : alarmAll.toString());
        return success(alarmPercentDto);
    }

    @GetMapping("/deviceView")
    public AjaxResult deviceView() {
        DeviceViewDto deviceViewDto = new DeviceViewDto();
        /** 总数 deviceCount */
        Integer deviceCount = itShouhuanInfoService.selectTShouhuanInfoAllCount();
        deviceViewDto.setDeviceCount(deviceCount == null ? 0 : deviceCount);
        /** 在线 deviceOnline */
        Integer deviceOnline = itShouhuanInfoService.selectTShouhuanInfoAllOnlineCount();
        deviceViewDto.setDeviceOnline(deviceOnline == null ? 0 : deviceOnline);
        /** 离线 un_deviceOnline */
        Integer un_deviceOnline = itShouhuanInfoService.selectTShouhuanInfoAllUnOnlineCount();
        deviceViewDto.setUn_deviceOnline(un_deviceOnline == null ? 0 : un_deviceOnline);
        /** 告警数 alarmCount */
        Integer alarmCount = tEarlyWarningService.selectTEarlyWarningUnCompletedAllCount();
        deviceViewDto.setAlarmCount(alarmCount == null ? 0 : alarmCount);
        return success(deviceViewDto);
    }

    @GetMapping("/deviceType")
    public AjaxResult deviceType() {
        Integer total = tDeviceListService.selectDeviceListCount();
        List<DeviceTypeDto> deviceListDto = tDeviceListService.selectDeviceListDto();
        for (DeviceTypeDto listDto : deviceListDto) {
            listDto.setDeviceStr(checkDeviceType(listDto.getDevice_model()));
            listDto.setDevicePercent(checkPercent(listDto.getCount(), total));
        }
        AjaxResult ajax = new AjaxResult();
        ajax.put("list", deviceListDto);
        ajax.put("total", total);
        return AjaxResult.success("操作成功", ajax);
    }

    @GetMapping("/userAgeAll")
    public AjaxResult userAgeAll() {
        Integer total = userProfileService.selectuserAgeCount();
        List<UserAgeDto> dtoList = userProfileService.selectuserAgeDto();
        dtoList.removeIf(user -> StringUtils.isNull(user.getAgeGroup()));
        AjaxResult ajax = new AjaxResult();
        ajax.put("list", dtoList);
        ajax.put("total", total);
        return AjaxResult.success("操作成功", ajax);
    }

    @GetMapping("/mapGpsView")
    public AjaxResult mapGpsView() {
        List<MapGpsDto> dtoList = itShouhuanInfoService.selectMapGpsView();
        AjaxResult ajax = new AjaxResult();
        ajax.put("lnglat", dtoList);
        AjaxResult ajax1 = new AjaxResult();
        ajax1.put("pointList", ajax);
        return AjaxResult.success("操作成功", ajax1);
    }

    @GetMapping("/mapGpsViewV2")
    public AjaxResult mapGpsViewV2() {   //TODO 暂时写在Controller中
        List<MapGpsDto> dtoList = itShouhuanInfoService.selectMapGpsView();
        List<AjaxResult> collect = new ArrayList<>();
        if (dtoList != null && !dtoList.isEmpty()) {
            collect = dtoList.stream()
                    .map(mapGpsDto -> {
                        AjaxResult ajax = new AjaxResult();
                        List<Float> list = new ArrayList<>();
                        if (mapGpsDto != null && mapGpsDto.getUse_gps_long() != null && mapGpsDto.getUse_gps_lat() != null) {
                            list.add(mapGpsDto.getUse_gps_long());
                            list.add(mapGpsDto.getUse_gps_lat());
                        }
                        ajax.put("lnglat", list);
                        return ajax;
                    }).filter(
                            person -> {
                                List<Float> lngList = (List<Float>) person.get("lnglat");
                                if (lngList != null && !lngList.isEmpty() && lngList.size() >= 2) {
                                    Float lng = lngList.get(0);
                                    Float lat = lngList.get(1);
                                    return lng > 0 && lat > 0;
                                }
                                return false;
                            }).collect(Collectors.toList());
        }
        return AjaxResult.success("操作成功", collect);
    }

    /**
     * 用户新增
     */
    @GetMapping("/addUser")
    public AjaxResult addUser() {
        List<AddUserDto> dtoList = userProfileService.selectAddUser();
        return success(dtoList);
    }

    /**
     * 设备新增
     */
    @GetMapping("/addDevice")
    public AjaxResult addDevice() {
        List<AddDeviceDto> dtoList = tDeviceListService.selectAddDevice();
        LocalDate currentDate = LocalDate.now();
        LocalDate lastMonthDate = currentDate.minusMonths(1);
        int year = currentDate.getYear();
        if (dtoList.size() == 2) {
            int lastMonth = lastMonthDate.getMonthValue() - 1;
            AddDeviceDto dto = new AddDeviceDto();
            dto.setMonth(year + "-0" + lastMonth);
            dto.setCount(0);
            dtoList.add(dto);
        } else if (dtoList.size() == 1) {
            int lastMonth = lastMonthDate.getMonthValue();
            int lastlastMonth = lastMonthDate.getMonthValue() - 1;
            AddDeviceDto dto = new AddDeviceDto();
            dto.setMonth(year + "-0" + lastMonth);
            dto.setCount(0);
            dtoList.add(dto);
            AddDeviceDto dto1 = new AddDeviceDto();
            dto1.setMonth(year + "-0" + lastlastMonth);
            dto1.setCount(0);
            dtoList.add(dto1);
        }
        dtoList = dtoList.stream().sorted(Comparator.comparing(AddDeviceDto::getMonth)).collect(Collectors.toList());
        return success(dtoList);
    }

    @GetMapping("/alarmStatusList")
    public AjaxResult alarmStatusList() {
        List<AlarmStatusListDto> dtoList = tShouhuanAlarmListService.selectAlarmStatusListDto();
        for (AlarmStatusListDto dto : dtoList) {
            dto.setAlarm_msg(tDeviceListService.checkMessage(dto.getAlarm_type()));
        }
        return success(dtoList);
    }

    /**
     * 设备总览
     */
    @GetMapping("/deviceOver")
    public AjaxResult deviceOver() {
        DeviceOverDto dto = new DeviceOverDto();
        dto.setBindDevice(tDeviceListService.selectDeviceListCount());
        dto.setBindUser(tDeviceListService.selectTDeviceListBandUser());
        dto.setDeviceOnline(tShouhuanAlarmListService.selectTShouhuanAlarmStatus());
        return success(dto);
    }

    /**
     * 查询SOS预警处理列表
     */
    @GetMapping("/alarmList")
    public AjaxResult alarmList(DataAlarmListDto dataAlarmListDto) {
        List<DataAlarmListDto> list = tShouhuanAlarmListService.selectTShouhuanAlarmList(dataAlarmListDto);
        List<MessageAlarmListDto> messageAlarmListDtoList = new ArrayList<>();
        if (list != null && !list.isEmpty()) {
            messageAlarmListDtoList = list.stream().map(
                    mapper -> {
                        MessageAlarmListDto alarmListDto = new MessageAlarmListDto();
                        alarmListDto.setName(mapper.getName());
                        alarmListDto.setAlarm_msg(tDeviceListService.checkMessage(mapper.getAlarm_type()));
                        alarmListDto.setTelno(mapper.getTel_one());
                        alarmListDto.setGps_long(mapper.getUse_gps_long());
                        alarmListDto.setGps_lat(mapper.getUse_gps_lat());
                        alarmListDto.setAddress(mapper.getLocation());
                        alarmListDto.setAlarm_type(mapper.getAlarm_type());
                        alarmListDto.setCreatetime(mapper.getCreatetime());
                        return alarmListDto;
                    }
            ).collect(Collectors.toList());
        }
        return success(messageAlarmListDtoList);
    }


    /**
     * 逆地理编码
     *
     * @param location
     * @return
     */
    public String getCounterLocation(String location) {

        Map<String, String> params = new HashMap<>();
        params.put("location", location);
        logger.info("获取逆地理编码,请求的参数为:{}", params);
        JSONObject map = locationUtils.getCounterLocation(params);
        LocationDto locationDto = com.alibaba.fastjson2.JSONObject.parseObject(String.valueOf(map), LocationDto.class);
        logger.info("获取逆地理编码,返回的请求结果为:{}", map);
        return locationDto.getFormatted_address();
    }

    /**
     * 计算百分比
     */
    public String checkPercent(int num1, int num2) {
        if (num1 == 0 || num2 == 0) {
            return "0.00";
        }
        // 将整数转换为BigDecimal类型
        BigDecimal bdNum1 = new BigDecimal(num1);
        BigDecimal bdNum2 = new BigDecimal(num2);
        // 计算百分比
        BigDecimal percentage = bdNum1.divide(bdNum2, 2, BigDecimal.ROUND_HALF_UP)
                .multiply(new BigDecimal(100));
        return percentage.toPlainString();
    }

    public String checkDeviceType(Integer device_model) {
        if (device_model == null) {
            return "null";
        }
        SysDictData date = new SysDictData();
        date.setDictType("sys_device_type");
        List<SysDictData> selectDictDataList = sysDictDataService.selectDictDataList(date);
        for (SysDictData sysDictData : selectDictDataList) {
            if (device_model == Integer.parseInt(sysDictData.getDictValue())) {
                return sysDictData.getDictLabel();
            }
        }
        return "null";
    }
}
