// The admin surface: discovery purge, system configuration, users & roles, the audit log, the
// scheduler + maintenance controls, the demo-account whitelist, and access invites. Only touches
// core's req. (Grouped by sub-area below; kept in one module as the cohesive "admin" domain.)
import { req } from "./core";

export interface DemoWhitelistEntry {
  id: number;
  email: string;
  note: string | null;
  added_by: string | null;
  created_at: string | null;
}

export interface Invite {
  id: number;
  email: string;
  status: "pending" | "approved" | "denied";
  note: string | null;
  requested_at: string | null;
  decided_at: string | null;
  decided_by: string | null;
}

// Admin Configuration page: one DB-overridable setting (registry entry on the backend).
export interface ConfigItem {
  key: string;
  type: "int" | "str" | "bool";
  group: string;
  secret: boolean;
  min: number | null;
  max: number | null;
  is_set: boolean; // a DB override row exists (else using the env/config default)
  allow_empty?: boolean; // if true, a blank field stores "" (explicit empty) rather than resetting
  value?: string | number | boolean; // non-secret: effective value
  default?: string | number | boolean; // non-secret: env/config default
  default_is_set?: boolean; // secret: whether an env default exists
}
export interface SystemConfigData {
  groups: Record<string, ConfigItem[]>;
  secrets_manageable: boolean;
}

// Admin Users & roles page.
export interface AdminUserRow {
  id: number;
  email: string;
  display_name: string | null;
  role: string; // "user" | "admin"
  is_active: boolean;
  is_suspended: boolean;
  email_verified: boolean;
  is_demo: boolean;
  has_password: boolean;
  has_google: boolean;
  created_at: string | null;
}

export interface AuditRow {
  id: number;
  created_at: string | null;
  actor: string | null; // email of the acting admin; null = System (scheduler/background)
  action: string; // canonical key, localized on the client via auditActions.<action>
  target_type: string | null;
  target_id: string | null;
  summary: string | null;
  before: Record<string, unknown> | null;
  after: Record<string, unknown> | null;
}
export interface AuditListResult {
  items: AuditRow[];
  total: number; // total rows in the log (may exceed `items` if capped)
  returned: number;
}

export interface SchedulerJob {
  id: string;
  interval_minutes: number;
  next_run: string | null;
  running: boolean;
  status: "ok" | "error" | "skipped" | null;
  last_started: string | null;
  last_finished: string | null;
  last_result: string | null;
  last_error: string | null;
  // Live progress while running (null when idle or for jobs that don't report it).
  // total is null for indeterminate progress (e.g. enrichment drains an unknown queue).
  progress: { current: number; total: number | null; phase: string | null } | null;
}

export interface SchedulerStatus {
  running_here: boolean;
  enabled: boolean;
  paused: boolean;
  jobs: SchedulerJob[];
  queue: {
    channels_recent_pending: number;
    channels_deep_pending: number;
    deep_eta_seconds: number;
    videos_pending_enrich: number;
    videos_pending_shorts: number;
    videos_live_refresh: number;
  };
  quota: {
    used_today: number;
    remaining_today: number;
    daily_budget: number;
    backfill_reserve: number;
  };
  maintenance: {
    revalidate_batch: number;
    revalidate_batch_default: number;
    min: number;
    max: number;
  };
}

export const adminApi = {
  // --- discovery / system configuration ---
  // Admin: reclaim all un-kept discovery content (search results + explored channels) now.
  purgeDiscovery: (): Promise<Record<string, number>> =>
    req("/api/admin/purge-discovery", { method: "POST" }),
  adminConfig: (): Promise<SystemConfigData> => req("/api/admin/config"),
  setConfig: (key: string, value: string | number | boolean): Promise<SystemConfigData> =>
    req(`/api/admin/config/${key}`, { method: "PATCH", body: JSON.stringify({ value }) }),
  resetConfig: (key: string): Promise<SystemConfigData> =>
    req(`/api/admin/config/${key}`, { method: "DELETE" }),
  testEmail: (): Promise<{ sent: boolean; to: string }> =>
    req("/api/admin/config/test-email", { method: "POST" }),
  // --- users & roles ---
  adminAudit: (limit = 500): Promise<AuditListResult> => req(`/api/admin/audit?limit=${limit}`),
  clearAudit: (): Promise<{ cleared: number }> => req("/api/admin/audit", { method: "DELETE" }),
  adminUsers: (): Promise<AdminUserRow[]> => req("/api/admin/users"),
  setUserRole: (id: number, role: "user" | "admin"): Promise<AdminUserRow> =>
    req(`/api/admin/users/${id}/role`, { method: "PATCH", body: JSON.stringify({ role }) }),
  setUserSuspended: (id: number, suspended: boolean): Promise<AdminUserRow> =>
    req(`/api/admin/users/${id}/suspend`, { method: "PATCH", body: JSON.stringify({ suspended }) }),
  adminDeleteUser: (id: number): Promise<{ deleted: number }> =>
    req(`/api/admin/users/${id}`, { method: "DELETE" }),
  // --- scheduler + maintenance ---
  schedulerStatus: (): Promise<SchedulerStatus> => req("/api/admin/scheduler"),
  updateSchedulerJob: (
    jobId: string,
    intervalMinutes: number,
  ): Promise<{ id: string; interval_minutes: number }> =>
    req(`/api/admin/scheduler/jobs/${jobId}`, {
      method: "PATCH",
      body: JSON.stringify({ interval_minutes: intervalMinutes }),
    }),
  runSchedulerJob: (jobId: string): Promise<{ id: string; started: boolean }> =>
    req(`/api/admin/scheduler/jobs/${jobId}/run`, { method: "POST" }),
  runAllSchedulerJobs: (): Promise<{ started: string[] }> =>
    req("/api/admin/scheduler/run-all", { method: "POST" }),
  updateMaintenanceBatch: (revalidateBatch: number): Promise<{ revalidate_batch: number }> =>
    req("/api/admin/scheduler/maintenance", {
      method: "PATCH",
      body: JSON.stringify({ revalidate_batch: revalidateBatch }),
    }),
  // --- demo whitelist ---
  adminDemoWhitelist: (): Promise<DemoWhitelistEntry[]> => req("/api/admin/demo/whitelist"),
  addDemoWhitelist: (email: string): Promise<DemoWhitelistEntry> =>
    req("/api/admin/demo/whitelist", { method: "POST", body: JSON.stringify({ email }) }),
  removeDemoWhitelist: (id: number) => req(`/api/admin/demo/whitelist/${id}`, { method: "DELETE" }),
  resetDemo: (): Promise<{ reset: boolean; playlists_seeded: number }> =>
    req("/api/admin/demo/reset", { method: "POST" }),
  // --- access invites ---
  adminInvites: (status?: string): Promise<Invite[]> =>
    req(`/api/admin/invites${status ? `?status=${status}` : ""}`),
  approveInvite: (id: number) => req(`/api/admin/invites/${id}/approve`, { method: "POST" }),
  denyInvite: (id: number) => req(`/api/admin/invites/${id}/deny`, { method: "POST" }),
  addInvite: (email: string) =>
    req("/api/admin/invites", { method: "POST", body: JSON.stringify({ email }) }),
};
