/**
 * Admin API Client
 * API functions for admin dashboard features
 */

import { getAuthHeaders } from "../context/AuthContext";

const API_BASE = import.meta.env.VITE_API_BASE || "http://localhost:3001/api";

async function adminFetch<T>(path: string, init?: RequestInit): Promise<T> {
  const url = `${API_BASE}${path}`;
  
  const response = await fetch(url, {
    ...init,
    headers: {
      "Content-Type": "application/json",
      ...getAuthHeaders(),
      ...init?.headers,
    },
  });
  
  const text = await response.text();
  
  if (!response.ok) {
    const error = text ? JSON.parse(text) : { message: "Request failed" };
    throw new Error(error.message || `Request failed: ${response.status}`);
  }
  
  return text ? JSON.parse(text) : ({} as T);
}

// ============================================
// USER MANAGEMENT
// ============================================

export type AdminUser = {
  id: number;
  username: string;
  email: string | null;
  full_name: string | null;
  role: "admin" | "user" | "viewer";
  is_active: number;
  last_login: string | null;
  created_at: string;
  updated_at: string;
};

export async function listUsers(): Promise<{ users: AdminUser[] }> {
  return adminFetch("/admin/users");
}

export async function getUser(userId: number): Promise<{ user: AdminUser }> {
  return adminFetch(`/admin/users/${userId}`);
}

export async function createUser(data: {
  username: string;
  password: string;
  email?: string;
  fullName?: string;
  role?: "admin" | "user" | "viewer";
}): Promise<{ user: AdminUser }> {
  return adminFetch("/admin/users", {
    method: "POST",
    body: JSON.stringify(data),
  });
}

export async function updateUser(
  userId: number,
  data: {
    email?: string;
    fullName?: string;
    role?: "admin" | "user" | "viewer";
    isActive?: boolean;
    password?: string;
  }
): Promise<{ user: AdminUser }> {
  return adminFetch(`/admin/users/${userId}`, {
    method: "PUT",
    body: JSON.stringify(data),
  });
}

export async function deleteUser(userId: number): Promise<{ message: string }> {
  return adminFetch(`/admin/users/${userId}`, {
    method: "DELETE",
  });
}

// ============================================
// CASES WITH FILTERS
// ============================================

export type AdminCase = {
  caseId: string;
  case_type: string;
  status: string;
  current_step: string | null;
  notes: string | null;
  analysis_result: any;
  landmarks_data: any;
  body_scan_path: string | null;
  created_by: number | null;
  created_by_username: string | null;
  created_at: string;
  updated_at: string;
};

export type ListCasesResponse = {
  cases: AdminCase[];
  total: number;
  limit: number;
  offset: number;
};

export async function listCasesAdmin(params?: {
  status?: string;
  createdBy?: number;
  search?: string;
  limit?: number;
  offset?: number;
  sortBy?: string;
  sortOrder?: "ASC" | "DESC";
}): Promise<ListCasesResponse> {
  const searchParams = new URLSearchParams();
  if (params?.status) searchParams.set("status", params.status);
  if (params?.createdBy) searchParams.set("createdBy", params.createdBy.toString());
  if (params?.search) searchParams.set("search", params.search);
  if (params?.limit) searchParams.set("limit", params.limit.toString());
  if (params?.offset) searchParams.set("offset", params.offset.toString());
  if (params?.sortBy) searchParams.set("sortBy", params.sortBy);
  if (params?.sortOrder) searchParams.set("sortOrder", params.sortOrder);
  
  const query = searchParams.toString();
  return adminFetch(`/admin/cases${query ? `?${query}` : ""}`);
}

// ============================================
// ANALYTICS
// ============================================

export type CaseStats = {
  total: number;
  byStatus: Record<string, number>;
  last7Days: { date: string; count: number }[];
  last30Days: { date: string; count: number }[];
};

export type UserStats = {
  total: number;
  active: number;
  inactive: number;
  byRole: Record<string, number>;
  recentLogins: number;
};

export type CobbAngleStats = {
  PT: { min: number; max: number; avg: number; count: number };
  MT: { min: number; max: number; avg: number; count: number };
  TL: { min: number; max: number; avg: number; count: number };
  totalCasesWithAngles: number;
};

export type ProcessingTimeStats = {
  min: number;
  max: number;
  avg: number;
  count: number;
};

export type BodyScanStats = {
  total: number;
  withBodyScan: number;
  withoutBodyScan: number;
  percentage: number;
};

export type DashboardAnalytics = {
  cases: CaseStats;
  users: UserStats;
  rigoDistribution: Record<string, number>;
  cobbAngles: CobbAngleStats;
  processingTime: ProcessingTimeStats;
  bodyScan: BodyScanStats;
};

export async function getDashboardAnalytics(): Promise<DashboardAnalytics> {
  return adminFetch("/admin/analytics/dashboard");
}

export async function getRigoDistribution(): Promise<{ distribution: Record<string, number> }> {
  return adminFetch("/admin/analytics/rigo");
}

export async function getCobbAngleStats(): Promise<{ stats: CobbAngleStats }> {
  return adminFetch("/admin/analytics/cobb-angles");
}

export async function getProcessingTimeStats(): Promise<{ stats: ProcessingTimeStats }> {
  return adminFetch("/admin/analytics/processing-time");
}

// ============================================
// AUDIT LOG
// ============================================

export type AuditLogEntry = {
  id: number;
  user_id: number | null;
  username: string | null;
  action: string;
  entity_type: string;
  entity_id: string | null;
  details: string | null;
  ip_address: string | null;
  created_at: string;
};

export async function getAuditLog(params?: {
  userId?: number;
  action?: string;
  entityType?: string;
  limit?: number;
  offset?: number;
}): Promise<{ entries: AuditLogEntry[] }> {
  const searchParams = new URLSearchParams();
  if (params?.userId) searchParams.set("userId", params.userId.toString());
  if (params?.action) searchParams.set("action", params.action);
  if (params?.entityType) searchParams.set("entityType", params.entityType);
  if (params?.limit) searchParams.set("limit", params.limit.toString());
  if (params?.offset) searchParams.set("offset", params.offset.toString());
  
  const query = searchParams.toString();
  return adminFetch(`/admin/audit-log${query ? `?${query}` : ""}`);
}
