import { fuzzyFindKnown, simplifyForMatch } from "./fuzzyMatch.js";

export type IkSimpleCatalogCategory = "weapon" | "character" | "material";

export interface IkSimpleCatalogEntry {
  normalizedName: string;
  good: string;
}

export interface IkCatalogItemMatch {
  matched: boolean;
  category: IkSimpleCatalogCategory;
  confidence: number;
  source: "ik-inventorylists";
  normalizedName?: string;
  good?: string;
  notes: string[];
}

export function matchIkCatalogItem(
  text: string,
  entries: readonly IkSimpleCatalogEntry[],
  category: IkSimpleCatalogCategory,
): IkCatalogItemMatch {
  const candidate = text.trim();
  if (!candidate) return reviewMatch(category, "No IK match text provided.");
  if (!entries.length) return reviewMatch(category, `IK ${category} catalog unavailable.`);

  const normalized = simplifyForMatch(candidate);
  const exact = entries.find((entry) =>
    entry.normalizedName === normalized || simplifyForMatch(entry.good) === normalized,
  );
  if (exact) return matched(category, exact, 100);

  const labels = entries.flatMap((entry) => [entry.normalizedName, entry.good]);
  const fuzzy = fuzzyFindKnown(candidate, labels, 0.78);
  if (!fuzzy) return reviewMatch(category, `IK ${category} not matched: ${candidate}.`);

  const entry = entries.find((item) => item.normalizedName === fuzzy.value || item.good === fuzzy.value);
  return entry
    ? matched(category, entry, Math.round(fuzzy.score * 100))
    : reviewMatch(category, `IK ${category} not matched: ${candidate}.`);
}

export function catalogSampleLabels(entries: readonly IkSimpleCatalogEntry[], count = 3) {
  return entries
    .slice(0, Math.max(0, count))
    .map((entry) => entry.good || entry.normalizedName)
    .filter(Boolean);
}

function matched(category: IkSimpleCatalogCategory, entry: IkSimpleCatalogEntry, confidence: number): IkCatalogItemMatch {
  return {
    matched: true,
    category,
    confidence,
    source: "ik-inventorylists",
    normalizedName: entry.normalizedName,
    good: entry.good,
    notes: [],
  };
}

function reviewMatch(category: IkSimpleCatalogCategory, note: string): IkCatalogItemMatch {
  return {
    matched: false,
    category,
    confidence: 0,
    source: "ik-inventorylists",
    notes: [note],
  };
}
