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.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.List;

@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 system,
            @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, system, startDate, endDate, page, pageSize)));
    }

    /** 按当前筛选条件全量导出埋点事件为 CSV（UTF-8 + BOM）。
     *  字段：ID / 事件类型 / 来源系统 / 用户标识 / IP地址 / 时间，按时间倒序。
     *  无数据或超上限时返回 JSON（application/json）供前端提示；成功返回 text/csv 文件。 */
    @GetMapping("/events/export")
    public ResponseEntity<?> exportEvents(
            @RequestParam(required = false) String eventType,
            @RequestParam(required = false) String system,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {
        var result = analyticsService.exportEvents(eventType, system, startDate, endDate);
        if (result.status() != AnalyticsService.EventExportResult.Status.SUCCESS) {
            return ResponseEntity.ok(ApiResponse.<Map<String, Object>>builder()
                    .code(422).message(result.message()).build());
        }
        String stamp = LocalDateTime.now(ZoneId.of("Asia/Shanghai"))
                .format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String filename = "埋点事件记录_" + stamp + ".csv";
        String encoded = URLEncoder.encode(filename, StandardCharsets.UTF_8).replace("+", "%20");
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded)
                .contentType(MediaType.parseMediaType("text/csv; charset=UTF-8"))
                .body(result.bytes());
    }

    @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");
        // 来源系统：用于区分不同系统的埋点，缺省归入 AI药典
        String system = body.get("system") instanceof String s && !s.isBlank()
                ? s : "AI药典";
        @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 : "", system);

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

    // ==================== 事件类型列表 ====================

    /** 获取所有事件类型，供前端切换 */
    @GetMapping("/event-types")
    public ResponseEntity<ApiResponse<List<String>>> getEventTypes() {
        return ResponseEntity.ok(ApiResponse.success(analyticsService.getEventTypes()));
    }

    // ==================== 来源系统列表 ====================

    /** 获取当前所有来源系统（AI药典恒在且首位），供前端系统切换下拉 */
    @GetMapping("/systems")
    public ResponseEntity<ApiResponse<List<String>>> getSystems() {
        return ResponseEntity.ok(ApiResponse.success(analyticsService.getSystems()));
    }

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

    /** 概览数字：total_events / active_users / page_views / searches / ai_qa
     *  range: today | yesterday | week (=近7天) | total (=累计) | custom
     *  custom 时传 startDate / endDate */
    @GetMapping("/stats/overview")
    public ResponseEntity<ApiResponse<Map<String, Object>>> queryOverview(
            @RequestParam(required = false) String range,
            @RequestParam(required = false) String system,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {
        return ResponseEntity.ok(ApiResponse.success(
                analyticsService.queryOverview(range != null ? range : "total", system, startDate, endDate)));
    }

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

    /** 分页维度统计：dimension=ip/url/type/user/user_ip */
    @GetMapping("/stats/dimension")
    public ResponseEntity<ApiResponse<Map<String, Object>>> queryDimension(
            @RequestParam String dimension,
            @RequestParam(required = false) String system,
            @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, system, startDate, endDate, page, pageSize)));
    }

    /** 浏览每次 AI 问答的耗时（按 request_id 关联前端 chat_complete 与后端 chat_stream_server 分段） */
    @GetMapping("/qa-sessions")
    public ResponseEntity<ApiResponse<Map<String, Object>>> queryQaSessions(
            @RequestParam(required = false) String system,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false) Long minTotalMs,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int pageSize) {
        return ResponseEntity.ok(ApiResponse.success(
                analyticsService.queryQaSessions(system, startDate, endDate, page, pageSize, minTotalMs)));
    }

    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";
    }
}
