import { CATALOG } from "@/lib/ledger/catalog";
import { tokenizeTitle } from "@/lib/ledger/parse";

export type Vocab = {
  tokenToId: Map<string, number>;
  idToToken: string[];
};

export function buildVocab(): Vocab {
  const tokenToId = new Map<string, number>();
  const idToToken: string[] = [];
  const add = (t: string) => {
    if (tokenToId.has(t)) return;
    tokenToId.set(t, idToToken.length);
    idToToken.push(t);
  };
  for (const inv of CATALOG) {
    for (const tok of tokenizeTitle(inv.title)) add(tok);
  }
  add("gold");
  add("heavy");
  add("quasicrystal");
  add("rhenium");
  add("thorium");
  add("iridium");
  add("graphene");
  add("oxide");
  add("gan");
  add("scaffold");
  add("epoxy");
  add("hydroxyl");
  add("carboxyl");
  for (const t of [
    "tungsten",
    "mercury",
    "thorium",
    "uranium",
    "californium",
    "copernicium",
    "livermorium",
  ]) {
    add(t);
  }
  return { tokenToId, idToToken };
}

export function encodeTitle(title: string, vocab: Vocab) {
  return tokenizeTitle(title).map((t) => vocab.tokenToId.get(t)).filter((n): n is number => n !== undefined);
}

export type Motif = { a: string; b: string; count: number };

export function metalMotifs(limit = 8): Motif[] {
  const counts = new Map<string, number>();
  for (const inv of CATALOG) {
    const parts = inv.title.match(/^([A-Za-z]+)-([A-Za-z]+)/);
    if (!parts) continue;
    const key = `${parts[1]} · ${parts[2]}`;
    counts.set(key, (counts.get(key) ?? 0) + 1);
  }
  return [...counts.entries()]
    .sort((a, b) => b[1] - a[1])
    .slice(0, limit)
    .map(([k, count]) => {
      const [a, b] = k.split(" · ");
      return { a, b, count };
    });
}
