package com.example.demo.controller;

import com.example.demo.model.Event;
import com.example.demo.model.dto.ApiResponse;
import com.example.demo.model.dto.EventDTO;
import com.example.demo.model.dto.EventQueryDTO;
import com.example.demo.model.enums.EventSourceType;
import com.example.demo.model.enums.EventStatus;
import com.example.demo.model.enums.ThreatLevel;
import com.example.demo.service.EventService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 事件管理控制器。
 * <p>
 * 提供事件接收、查询、处理等 RESTful API 接口。
 * 对应外部接口 IF-01 / SRS-EHTG_I_EVT 和 IF-02 / SRS-EHTG_I_UI。
 * </p>
 *
 * @requirement(name="事件接收与解析", id="SRS-EHTG-01")
 * 通过HTTP POST接收上游传感器的原始事件数据。
 *
 * @requirement(name="前端可视化展示", id="SRS-EHTG-04")
 * 提供Web界面展示事件列表，支持排序、筛选和操作反馈。
 */
@Tag(name = "事件管理 (EHTG)", description = "事件处理与任务生成模块 - 事件接收、查询、处理接口")
@RestController
@RequestMapping("/api/v1/events")
public class EventController {

    private static final Logger log = LoggerFactory.getLogger(EventController.class);

    private final EventService eventService;

    public EventController(EventService eventService) {
        this.eventService = eventService;
    }

    /**
     * 接收原始事件。
     * <p>
     * 对应外部接口 IF-01，接收上游传感器融合模块的原始事件数据。
     * </p>
     *
     * @param eventDTO 事件数据
     * @return 处理后的标准化事件
     */
    @Operation(summary = "接收原始事件", description = "接收上游传感器融合模块的原始事件数据，执行数据清洗与标准化")
    @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ApiResponse<Event> receiveEvent(@Valid @RequestBody EventDTO eventDTO) {
        log.info("接收到事件请求，来源: {}", eventDTO.getSourceType());

        Event rawEvent = convertToEvent(eventDTO);
        Event processedEvent = eventService.receiveEvent(rawEvent);

        return ApiResponse.success("事件接收并处理成功", processedEvent);
    }

    /**
     * 查询事件列表。
     * <p>
     * 支持按状态筛选、按字段排序和分页。
     * </p>
     *
     * @param query 查询参数
     * @return 事件列表
     */
    @Operation(summary = "查询事件列表", description = "查询事件列表，支持状态筛选、排序和分页")
    @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public ApiResponse<List<Event>> listEvents(@Valid EventQueryDTO query) {
        List<Event> events = eventService.queryEvents(query);
        return ApiResponse.success(events);
    }

    /**
     * 查询事件详情。
     *
     * @param eventId 事件ID
     * @return 事件详情
     */
    @Operation(summary = "查询事件详情", description = "根据事件ID查询事件详细信息")
    @GetMapping(value = "/{eventId}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ApiResponse<Event> getEvent(@Parameter(description = "事件ID") @PathVariable String eventId) {
        Optional<Event> eventOpt = eventService.getEventById(eventId);
        return eventOpt.map(ApiResponse::success)
                .orElseGet(() -> ApiResponse.error(404, "事件不存在: " + eventId));
    }

    /**
     * 处理事件（更新状态）。
     *
     * @param eventId 事件ID
     * @param status  新状态
     * @return 更新后的事件
     */
    @Operation(summary = "处理事件", description = "更新事件处理状态")
    @PutMapping(value = "/{eventId}/process", produces = MediaType.APPLICATION_JSON_VALUE)
    public ApiResponse<Event> processEvent(
            @Parameter(description = "事件ID") @PathVariable String eventId,
            @Parameter(description = "目标状态：PENDING / PROCESSING / COMPLETED / IGNORED / ERROR")
            @RequestParam String status) {
        EventStatus eventStatus = EventStatus.valueOf(status.toUpperCase());
        Optional<Event> updated = eventService.updateEventStatus(eventId, eventStatus);
        return updated.map(ApiResponse::success)
                .orElseGet(() -> ApiResponse.error(404, "事件不存在: " + eventId));
    }

    /**
     * 将 DTO 转换为实体。
     */
    private Event convertToEvent(EventDTO dto) {
        Event event = new Event();
        event.setEventId(dto.getEventId());
        event.setSourceType(dto.getSourceType());
        event.setOccurTime(dto.getOccurTime());
        event.setLocation(dto.getLocation());
        event.setConfidence(dto.getConfidence());
        event.setThreatLevel(dto.getThreatLevel());
        event.setEventType(dto.getEventType());
        event.setStatus(EventStatus.PENDING);
        event.setCreateTime(LocalDateTime.now());
        event.setUpdateTime(LocalDateTime.now());
        return event;
    }
}
