package com.pharmacopoeia.controller;

import com.pharmacopoeia.dto.ApiResponse;
import com.pharmacopoeia.service.AnalyticsService;
import com.pharmacopoeia.util.IpUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/v1/analytics")
public class AnalyticsController {

    private final AnalyticsService analyticsService;
    private final HttpServletRequest request;

    public AnalyticsController(AnalyticsService analyticsService, HttpServletRequest request) {
        this.analyticsService = analyticsService;
        this.request = request;
    }

    // ==================== 事件 ====================

    @GetMapping("/events")
    public ResponseEntity<ApiResponse<Map<String, Object>>> queryEvents(
            @RequestParam(required = false) String eventType,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int pageSize) {
        return ResponseEntity.ok(ApiResponse.success(
                analyticsService.queryEvents(eventType, startDate, endDate, page, pageSize)));
    }

    @GetMapping("/events/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getEventDetail(@PathVariable long id) {
        var detail = analyticsService.getEventDetail(id);
        if (detail.isEmpty()) {
            return ResponseEntity.ok(ApiResponse.<Map<String, Object>>builder().code(404).message("事件不存在").build());
        }
        return ResponseEntity.ok(ApiResponse.success(detail));
    }

    @PostMapping("/events")
    public ResponseEntity<ApiResponse<Map<String, String>>> saveEvent(@RequestBody Map<String, Object> body) {
        String eventType = (String) body.getOrDefault("event_type", "unknown");
        @SuppressWarnings("unchecked")
        Map<String, Object> eventData = body.get("event_data") instanceof Map
                ? (Map<String, Object>) body.get("event_data") : Map.of();
        String pageUrl = (String) body.getOrDefault("page_url", "");
        String referrer = (String) body.getOrDefault("referrer", "");

        String userKey = getCurrentUserKey();
        String ip = IpUtils.getClientIp(request);
        String ua = request.getHeader("User-Agent");

        analyticsService.saveEvent(userKey, eventType, eventData, pageUrl, referrer,
                ip, ua != null ? ua : "");

        return ResponseEntity.accepted()
                .body(ApiResponse.<Map<String, String>>builder().code(202).message("accepted")
                        .data(Map.of("status", "accepted")).build());
    }

    // ==================== 概览 ====================

    /** 概览数字：total_events / active_users / page_views / searches / ai_qa */
    @GetMapping("/stats/overview")
    public ResponseEntity<ApiResponse<Map<String, Object>>> queryOverview(
            @RequestParam(required = false) String range) {
        if (range == null || range.isBlank()) {
            range = "total";
        }
        return ResponseEntity.ok(ApiResponse.success(analyticsService.queryOverview(range)));
    }

    // ==================== 维度 ====================

    /** 分页维度统计：dimension=ip/url/type/user/user_ip */
    @GetMapping("/stats/dimension")
    public ResponseEntity<ApiResponse<Map<String, Object>>> queryDimension(
            @RequestParam String dimension,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int pageSize) {
        return ResponseEntity.ok(ApiResponse.success(
                analyticsService.queryDimension(dimension, startDate, endDate, page, pageSize)));
    }

    private String getCurrentUserKey() {
        var auth = org.springframework.security.core.context.SecurityContextHolder
                .getContext().getAuthentication();
        if (auth != null && auth.isAuthenticated()
                && !"anonymousUser".equals(auth.getPrincipal())) {
            return auth.getName();
        }
        return "anonymous";
    }
}
