package com.writeoff.module.observability.controller;

import com.writeoff.common.api.ApiResponse;
import com.writeoff.module.observability.dto.CreateAlertRuleRequest;
import com.writeoff.module.observability.dto.UpdateAlertRuleRequest;
import com.writeoff.module.observability.model.AlertEventInfo;
import com.writeoff.module.observability.model.AlertRuleInfo;
import com.writeoff.module.observability.model.ObservabilityMetricPoint;
import com.writeoff.module.observability.service.ObservabilityService;
import com.writeoff.security.DataScopeType;
import com.writeoff.security.RequirePermission;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/observability")
public class ObservabilityController {
    private final ObservabilityService observabilityService;

    public ObservabilityController(ObservabilityService observabilityService) {
        this.observabilityService = observabilityService;
    }

    @GetMapping("/metrics")
    @RequirePermission(value = "observability.read", dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "OBSERVABILITY_METRICS")
    public ApiResponse<List<ObservabilityMetricPoint>> metrics(@RequestParam("metricCode") String metricCode,
                                                               @RequestParam(value = "minutes", required = false, defaultValue = "60") int minutes) {
        return ApiResponse.success(observabilityService.queryMetric(metricCode, minutes));
    }

    @GetMapping("/metrics/export")
    @RequirePermission(value = "observability.read", dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "OBSERVABILITY_METRICS_EXPORT")
    public ApiResponse<Map<String, Object>> exportMetrics(@RequestParam(value = "minutes", required = false, defaultValue = "60") int minutes) {
        return ApiResponse.success(observabilityService.exportMetricSummary(minutes));
    }

    @GetMapping("/alert-rules")
    @RequirePermission(value = "observability.read", dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "OBSERVABILITY_RULE_LIST")
    public ApiResponse<List<AlertRuleInfo>> rules() {
        return ApiResponse.success(observabilityService.listRules());
    }

    @PostMapping("/alert-rules")
    @RequirePermission(value = "observability.manage", dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "OBSERVABILITY_RULE_CREATE")
    public ApiResponse<AlertRuleInfo> createRule(@RequestBody @Valid CreateAlertRuleRequest request) {
        return ApiResponse.success(observabilityService.createRule(request));
    }

    @PutMapping("/alert-rules/{id}")
    @RequirePermission(value = "observability.manage", dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "OBSERVABILITY_RULE_UPDATE")
    public ApiResponse<AlertRuleInfo> updateRule(@PathVariable("id") Long id,
                                                 @RequestBody @Valid UpdateAlertRuleRequest request) {
        return ApiResponse.success(observabilityService.updateRule(id, request));
    }

    @PostMapping("/alert-rules/evaluate")
    @RequirePermission(value = "observability.manage", dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "OBSERVABILITY_RULE_EVALUATE")
    public ApiResponse<Map<String, Object>> evaluateRules() {
        return ApiResponse.success(observabilityService.evaluateRules());
    }

    @PostMapping("/alert-rules/evaluate/auto")
    @RequirePermission(value = "observability.manage", dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "OBSERVABILITY_RULE_EVALUATE_AUTO")
    public ApiResponse<Map<String, Object>> evaluateRulesAuto(@RequestParam(value = "recoveryWindowMinute", required = false, defaultValue = "10") int recoveryWindowMinute) {
        return ApiResponse.success(observabilityService.evaluateRulesAuto(recoveryWindowMinute));
    }

    @GetMapping("/alert-events")
    @RequirePermission(value = "observability.read", dataScope = DataScopeType.GLOBAL_READONLY, auditAction = "OBSERVABILITY_EVENT_LIST")
    public ApiResponse<List<AlertEventInfo>> events() {
        return ApiResponse.success(observabilityService.listEvents());
    }
}
