package com.dne.ems.controller;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.dne.ems.dto.AqiDistributionDTO;
import com.dne.ems.dto.AqiHeatmapPointDTO;
import com.dne.ems.dto.DashboardStatsDTO;
import com.dne.ems.dto.GridCoverageDTO;
import com.dne.ems.dto.HeatmapPointDTO;
import com.dne.ems.dto.PollutantThresholdDTO;
import com.dne.ems.dto.PollutionStatsDTO;
import com.dne.ems.dto.TaskStatsDTO;
import com.dne.ems.dto.TrendDataPointDTO;
import com.dne.ems.service.DashboardService;

import lombok.RequiredArgsConstructor;

/**
 * 仪表盘数据控制器，提供各类环境监测数据的统计和可视化接口
 *
 * <p>主要功能包括：
 * <ul>
 *   <li>环境质量指标统计</li>
 *   <li>AQI数据分布和热力图</li>
 *   <li>污染物阈值管理</li>
 *   <li>任务完成情况统计</li>
 *   <li>各类趋势分析数据</li>
 * </ul>
 *
 * @author DNE开发团队
 * @version 1.0
 * @since 2024
 */
@RestController
@RequestMapping("/api/dashboard")
@RequiredArgsConstructor
public class DashboardController {

    private final DashboardService dashboardService;
    private static final Logger log = LoggerFactory.getLogger(DashboardController.class);

    /**
     * 获取仪表盘核心统计数据
     *
     * @return 包含各类核心统计数据的响应实体
     * @see DashboardStatsDTO
     */
    @GetMapping("/stats")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<DashboardStatsDTO> getDashboardStats() {
        DashboardStatsDTO stats = dashboardService.getDashboardStats();
        return ResponseEntity.ok(stats);
    }

    /**
     * 获取AQI等级分布数据
     *
     * @return 包含各AQI等级分布数据的响应实体
     * @see AqiDistributionDTO
     */
    @GetMapping("/reports/aqi-distribution")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<List<AqiDistributionDTO>> getAqiDistribution() {
        List<AqiDistributionDTO> distribution = dashboardService.getAqiDistribution();
        return ResponseEntity.ok(distribution);
    }

    /**
     * 获取月度超标趋势数据
     *
     * @return 包含月度超标趋势数据的响应实体
     * @see TrendDataPointDTO
     */
    @GetMapping("/reports/monthly-exceedance-trend")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<List<TrendDataPointDTO>> getMonthlyExceedanceTrend() {
        List<TrendDataPointDTO> trend = dashboardService.getMonthlyExceedanceTrend();
        return ResponseEntity.ok(trend);
    }

    /**
     * 获取网格覆盖情况数据
     *
     * @return 包含各城市网格覆盖情况的响应实体
     * @see GridCoverageDTO
     */
    @GetMapping("/reports/grid-coverage")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<List<GridCoverageDTO>> getGridCoverage() {
        List<GridCoverageDTO> coverage = dashboardService.getGridCoverageByCity();
        return ResponseEntity.ok(coverage);
    }

    /**
     * 获取反馈热力图数据
     *
     * @return 包含热力图坐标点数据的响应实体
     * @throws ResourceNotFoundException 如果未找到任何热力图数据
     * @see HeatmapPointDTO
     */
    @GetMapping("/map/heatmap")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<List<HeatmapPointDTO>> getHeatmapData() {
        List<HeatmapPointDTO> heatmapData = dashboardService.getHeatmapData();
        if (heatmapData == null || heatmapData.isEmpty()) {
            log.warn("反馈热力图数据为空");
        } else {
            log.info("成功获取反馈热力图数据，共 {} 个数据点", heatmapData.size());
        }
        return ResponseEntity.ok(heatmapData);
    }

    /**
     * 获取污染物统计报告数据
     *
     * @return 包含各类污染物统计数据的响应实体
     * @see PollutionStatsDTO
     */
    @GetMapping("/reports/pollution-stats")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<List<PollutionStatsDTO>> getPollutionStats() {
        List<PollutionStatsDTO> stats = dashboardService.getPollutionStats();
        return ResponseEntity.ok(stats);
    }

    /**
     * 获取任务完成情况统计数据
     *
     * @return 包含任务完成率等统计数据的响应实体
     * @see TaskStatsDTO
     */
    @GetMapping("/reports/task-completion-stats")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<TaskStatsDTO> getTaskCompletionStats() {
        TaskStatsDTO stats = dashboardService.getTaskCompletionStats();
        return ResponseEntity.ok(stats);
    }

    /**
     * 获取AQI热力图数据
     *
     * @return 包含AQI热力图坐标点数据的响应实体
     * @throws ResourceNotFoundException 如果未找到任何AQI数据
     * @see AqiHeatmapPointDTO
     */
    @GetMapping("/map/aqi-heatmap")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<List<AqiHeatmapPointDTO>> getAqiHeatmapData() {
        List<AqiHeatmapPointDTO> heatmapData = dashboardService.getAqiHeatmapData();
        if (heatmapData == null || heatmapData.isEmpty()) {
            log.warn("AQI热力图数据为空");
        } else {
            log.info("成功获取AQI热力图数据，共 {} 个数据点", heatmapData.size());
        }
        return ResponseEntity.ok(heatmapData);
    }

    /**
     * 获取所有污染物阈值设置
     *
     * @return 包含所有污染物阈值设置的响应实体
     * @see PollutantThresholdDTO
     */
    @GetMapping("/thresholds")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<List<PollutantThresholdDTO>> getPollutantThresholds() {
        log.info("接收到获取所有污染物阈值设置的请求");
        List<PollutantThresholdDTO> thresholds = dashboardService.getPollutantThresholds();
        log.info("返回 {} 个污染物阈值设置", thresholds.size());
        return ResponseEntity.ok(thresholds);
    }

    /**
     * 获取指定污染物的阈值设置
     *
     * @param pollutantName 污染物名称
     * @return 包含指定污染物阈值设置的响应实体
     * @throws ResourceNotFoundException 如果未找到该污染物的阈值设置
     * @see PollutantThresholdDTO
     */
    @GetMapping("/thresholds/{pollutantName}")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<PollutantThresholdDTO> getPollutantThreshold(@PathVariable String pollutantName) {
        log.info("接收到获取污染物 {} 阈值设置的请求", pollutantName);
        PollutantThresholdDTO threshold = dashboardService.getPollutantThreshold(pollutantName);
        if (threshold == null) {
            log.warn("未找到污染物 {} 的阈值设置", pollutantName);
            return ResponseEntity.notFound().build();
        }
        log.info("返回污染物 {} 的阈值设置: {}", pollutantName, threshold);
        return ResponseEntity.ok(threshold);
    }

    /**
     * 保存污染物阈值设置
     *
     * @param thresholdDTO 包含阈值设置的数据传输对象
     * @return 包含已保存阈值设置的响应实体
     * @throws IllegalArgumentException 如果阈值设置无效
     * @see PollutantThresholdDTO
     */
    @PostMapping("/thresholds")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<PollutantThresholdDTO> savePollutantThreshold(@RequestBody PollutantThresholdDTO thresholdDTO) {
        log.info("接收到保存污染物阈值设置的请求: {}", thresholdDTO);
        PollutantThresholdDTO saved = dashboardService.savePollutantThreshold(thresholdDTO);
        log.info("污染物阈值设置已保存: {}", saved);
        return ResponseEntity.ok(saved);
    }

    /**
     * 获取各类污染物的月度趋势数据
     *
     * @return 包含各类污染物月度趋势数据的响应实体
     * @see TrendDataPointDTO
     */
    @GetMapping("/reports/pollutant-monthly-trends")
    @PreAuthorize("hasAnyRole('DECISION_MAKER', 'ADMIN')")
    public ResponseEntity<Map<String, List<TrendDataPointDTO>>> getPollutantMonthlyTrends() {
        log.info("接收到获取每种污染物月度趋势数据的请求");
        Map<String, List<TrendDataPointDTO>> trends = dashboardService.getPollutantMonthlyTrends();
        log.info("返回 {} 种污染物的趋势数据", trends.size());
        return ResponseEntity.ok(trends);
    }
}