/**
 * KPI/통계 API 서비스
 * - 실제 백엔드 API 호출 (GET /api/stats/kpi, /api/stats/monthly)
 * - 하위 호환용 변환 헬퍼 제공
 */
import type { KpiMetric, MonthlyTrend, ViolationType } from '@data/mock/kpi';

const API_BASE = import.meta.env.VITE_API_URL ?? '/api';

// ─── 백엔드 API 응답 타입 ───────────────────

export interface PredictionKpi {
  kpiKey: string;
  kpiLabel: string;
  value: number;
  trend: string | null; // 'up', 'down', 'flat'
  deltaPct: number | null;
  updatedAt: string;
}

export interface PredictionStatsMonthly {
  statMonth: string; // '2026-04-01' (DATE -> ISO string)
  totalDetections: number;
  totalEnforcements: number;
  byCategory: Record<string, number> | null;
  byZone: Record<string, number> | null;
  byRiskLevel: Record<string, number> | null;
  byGearType: Record<string, number> | null;
  byViolationType: Record<string, number> | null;
  eventCount: number;
  criticalEventCount: number;
  falsePositiveCount: number;
  aiAccuracyPct: number | null;
}

// ─── API 호출 ───────────────────

export async function getKpiMetrics(): Promise<PredictionKpi[]> {
  const res = await fetch(`${API_BASE}/stats/kpi`, { credentials: 'include' });
  if (!res.ok) throw new Error(`API error: ${res.status}`);
  return res.json();
}

export async function getMonthlyStats(
  from: string,
  to: string,
): Promise<PredictionStatsMonthly[]> {
  const res = await fetch(`${API_BASE}/stats/monthly?from=${from}&to=${to}`, {
    credentials: 'include',
  });
  if (!res.ok) throw new Error(`API error: ${res.status}`);
  return res.json();
}

export interface PredictionStatsDaily {
  statDate: string;
  totalDetections: number;
  enforcementCount: number;
  eventCount: number;
  criticalEventCount: number;
  byCategory: Record<string, number> | null;
  byZone: Record<string, number> | null;
  byRiskLevel: Record<string, number> | null;
  byGearType: Record<string, number> | null;
  byViolationType: Record<string, number> | null;
  aiAccuracyPct: number | null;
}

export interface PredictionStatsHourly {
  statHour: string;
  totalDetections: number;
  eventCount: number;
  criticalCount: number;
  byCategory: Record<string, number> | null;
  byZone: Record<string, number> | null;
  byRiskLevel: Record<string, number> | null;
}

export async function getDailyStats(
  from: string,
  to: string,
): Promise<PredictionStatsDaily[]> {
  const res = await fetch(`${API_BASE}/stats/daily?from=${from}&to=${to}`, {
    credentials: 'include',
  });
  if (!res.ok) throw new Error(`API error: ${res.status}`);
  return res.json();
}

export async function getHourlyStats(
  hours: number = 24,
): Promise<PredictionStatsHourly[]> {
  const res = await fetch(`${API_BASE}/stats/hourly?hours=${hours}`, {
    credentials: 'include',
  });
  if (!res.ok) throw new Error(`API error: ${res.status}`);
  return res.json();
}

// ─── 하위 호환 변환 헬퍼 ───────────────────

/** PredictionKpi -> 기존 KpiMetric 형태로 변환 (Dashboard에서 사용) */
export function toKpiMetric(kpi: PredictionKpi): KpiMetric {
  return {
    id: kpi.kpiKey,
    label: kpi.kpiLabel,
    value: kpi.value,
    prev: kpi.deltaPct
      ? Math.round(kpi.value / (1 + kpi.deltaPct / 100))
      : undefined,
  };
}

/** PredictionStatsMonthly -> MonthlyTrend 변환 */
export function toMonthlyTrend(stat: PredictionStatsMonthly): MonthlyTrend {
  return {
    month: stat.statMonth.substring(0, 7), // '2026-04-01' -> '2026-04'
    enforce: stat.totalEnforcements ?? 0,
    detect: stat.totalDetections ?? 0,
    accuracy: stat.aiAccuracyPct ?? 0,
  };
}

/** MonthlyStats의 byViolationType -> ViolationType[] 변환 (기간 합산) */
export function toViolationTypes(
  stats: PredictionStatsMonthly[],
): ViolationType[] {
  const totals: Record<string, number> = {};
  stats.forEach((s) => {
    if (s.byViolationType) {
      Object.entries(s.byViolationType).forEach(([k, v]) => {
        totals[k] = (totals[k] ?? 0) + (v as number);
      });
    }
  });
  const sum = Object.values(totals).reduce((a, b) => a + b, 0);
  return Object.entries(totals)
    .map(([type, count]) => ({
      type,
      count,
      pct: sum > 0 ? Math.round((count / sum) * 100) : 0,
    }))
    .sort((a, b) => b.count - a.count);
}
