import { invoke } from "@tauri-apps/api/core";

export type GenerationKind =
  | "npc"
  | "encounter"
  | "world"
  | "item"
  | "quest"
  | "session"
  | "image";

export interface GenerationSummary {
  id: number;
  kind: GenerationKind;
  title: string;
  /** Epoch ms */
  createdAt: number;
}

export interface Generation {
  id: number;
  kind: GenerationKind;
  title: string;
  /** Raw JSON string from the LLM (or data URL for image kind). */
  data: string;
  source: string | null;
  createdAt: number;
}

export interface AddGenerationRequest {
  kind: GenerationKind;
  title: string;
  data: string;
  source?: string;
}

// ponytail: thin wrapper. Every generator that succeeds calls addGeneration;
// the History view lists/gets/deletes via these helpers.

export async function addGeneration(req: AddGenerationRequest): Promise<number> {
  return invoke<number>("generation_add", { req });
}

export async function listGenerations(
  kind?: GenerationKind,
): Promise<GenerationSummary[]> {
  return invoke<GenerationSummary[]>("generation_list", { kind: kind ?? null });
}

export async function getGeneration(id: number): Promise<Generation | null> {
  return invoke<Generation | null>("generation_get", { id });
}

export async function deleteGeneration(id: number): Promise<number> {
  return invoke<number>("generation_delete", { id });
}

export async function clearAllGenerations(): Promise<number> {
  return invoke<number>("generation_delete", { id: null });
}

export async function generationCounts(): Promise<Record<string, number>> {
  const pairs = await invoke<[string, number][]>("generation_counts");
  return Object.fromEntries(pairs);
}

// ─── Title extraction ────────────────────────────────────────

// ponytail: each LLM response shape has a slightly different "title" field.
// Centralize so the history list can label rows without re-parsing in the UI.

const TITLE_KEYS: Record<GenerationKind, string[]> = {
  npc: ["name"],
  encounter: ["title"],
  world: ["name"],
  item: ["name"],
  quest: ["title"],
  session: ["title"],
  image: [],
};

/**
 * Pull a human-readable title out of an LLM JSON string. Falls back to the
 * caller's `fallback` if the JSON is malformed or has no recognized field.
 */
export function extractTitle(
  kind: GenerationKind,
  data: string,
  fallback: string,
): string {
  try {
    const obj = JSON.parse(data);
    for (const k of TITLE_KEYS[kind]) {
      const v = obj?.[k];
      if (typeof v === "string" && v.trim()) return v.trim();
    }
  } catch {
    // Not JSON — for image kind the data is a base64 PNG data URL.
  }
  return fallback;
}

// ─── Time formatting ─────────────────────────────────────────

/** Compact relative time for the history list: "just now", "3m", "2h", "5d". */
export function relativeTime(epochMs: number, now: number = Date.now()): string {
  const diff = Math.max(0, now - epochMs);
  const s = Math.floor(diff / 1000);
  if (s < 45) return "just now";
  const m = Math.floor(s / 60);
  if (m < 60) return `${m}m ago`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h ago`;
  const d = Math.floor(h / 24);
  if (d < 30) return `${d}d ago`;
  const date = new Date(epochMs);
  return date.toLocaleDateString();
}

// ─── Defaults (one source of truth for kind label/icon) ──────

export const KIND_LABELS: Record<GenerationKind, string> = {
  npc: "NPC",
  encounter: "Encounter",
  world: "World",
  item: "Item",
  quest: "Quest",
  session: "Session",
  image: "Image",
};

export const KIND_ORDER: GenerationKind[] = [
  "npc",
  "encounter",
  "world",
  "item",
  "quest",
  "session",
  "image",
];
