import type { TrustState } from "@app/shared-types";

export type SearchResultItem = {
  displayName: string;
  quantity: number;
  unit: string;
  locationName: string;
  locationType: string;
  sublocation: string | null;
  trustState: TrustState;
  trustScore: number;
};

function lang(languageTag: string): string {
  return (languageTag.split("-")[0] ?? "sv").toLowerCase();
}

const TRUST_HEDGE: Record<TrustState, Record<string, string>> = {
  trusted: {
    sv: "Jag är ganska säker på att den finns kvar.",
    en: "I'm fairly sure it's still there.",
    da: "Jeg er ret sikker på, at den stadig er der.",
    de: "Ich bin mir ziemlich sicher, dass es noch da ist.",
    es: "Estoy bastante seguro de que sigue ahí.",
    fi: "Olen melko varma, että se on edelleen siellä.",
    fr: "Je suis assez sûr qu'il est toujours là.",
    it: "Sono abbastanza sicuro che sia ancora lì.",
    nb: "Jeg er ganske sikker på at den fremdeles er der.",
    nl: "Ik ben redelijk zeker dat het er nog steeds is.",
    pl: "Jestem dość pewien, że wciąż tam jest.",
    pt: "Estou bastante certo de que ainda está lá.",
  },
  decaying: {
    sv: "Jag är lite osäker – det var ett tag sedan den uppdaterades.",
    en: "I'm a bit unsure – it hasn't been updated in a while.",
    da: "Jeg er lidt usikker – det er et stykke tid siden, den blev opdateret.",
    de: "Ich bin mir etwas unsicher – es wurde schon eine Weile nicht mehr aktualisiert.",
    es: "No estoy muy seguro: hace tiempo que no se actualiza.",
    fi: "Olen hieman epävarma – sitä ei ole päivitetty vähään aikaan.",
    fr: "Je ne suis pas très sûr – cela fait un moment qu'il n'a pas été mis à jour.",
    it: "Non sono molto sicuro: non viene aggiornato da un po'.",
    nb: "Jeg er litt usikker – det er en stund siden den ble oppdatert.",
    nl: "Ik ben een beetje onzeker – het is al een tijdje niet meer bijgewerkt.",
    pl: "Nie jestem pewien – od dawna nie było aktualizacji.",
    pt: "Não tenho muita certeza: já faz algum tempo desde a última atualização.",
  },
  stale: {
    sv: "Jag är osäker – den här posten är gammal och kanske inte stämmer längre.",
    en: "I'm unsure – this entry is old and may no longer be accurate.",
    da: "Jeg er usikker – denne post er gammel og passer måske ikke længere.",
    de: "Ich bin unsicher – dieser Eintrag ist alt und möglicherweise nicht mehr aktuell.",
    es: "No estoy seguro: esta entrada es antigua y quizás ya no sea correcta.",
    fi: "Olen epävarma – tämä merkintä on vanha eikä välttämättä pidä enää paikkaansa.",
    fr: "Je ne suis pas sûr – cette entrée est ancienne et pourrait ne plus être exacte.",
    it: "Non ne sono sicuro: questa voce è vecchia e potrebbe non essere più accurata.",
    nb: "Jeg er usikker – denne posten er gammel og stemmer kanskje ikke lenger.",
    nl: "Ik ben onzeker – dit item is oud en is mogelijk niet meer accuraat.",
    pl: "Nie jestem pewien – ten wpis jest stary i może nie być już aktualny.",
    pt: "Não tenho a certeza: esta entrada é antiga e pode já não estar correta.",
  },
  unverified: {
    sv: "Jag är osäker – posten är ännu inte verifierad.",
    en: "I'm unsure – this entry hasn't been verified yet.",
    da: "Jeg er usikker – posten er endnu ikke bekræftet.",
    de: "Ich bin unsicher – dieser Eintrag wurde noch nicht verifiziert.",
    es: "No estoy seguro: esta entrada aún no ha sido verificada.",
    fi: "Olen epävarma – tätä merkintää ei ole vielä vahvistettu.",
    fr: "Je ne suis pas sûr – cette entrée n'a pas encore été vérifiée.",
    it: "Non ne sono sicuro: questa voce non è stata ancora verificata.",
    nb: "Jeg er usikker – posten er ikke verifisert ennå.",
    nl: "Ik ben onzeker – dit item is nog niet geverifieerd.",
    pl: "Nie jestem pewien – ten wpis nie został jeszcze zweryfikowany.",
    pt: "Não tenho a certeza: esta entrada ainda não foi verificada.",
  },
};

const LOCATION_TEMPLATES: Record<string, Record<string, string>> = {
  sv: {
    withSublocation: "i {{location}} ({{sublocation}})",
    withoutSublocation: "i {{location}}",
  },
  en: {
    withSublocation: "in the {{location}} ({{sublocation}})",
    withoutSublocation: "in the {{location}}",
  },
  da: {
    withSublocation: "i {{location}} ({{sublocation}})",
    withoutSublocation: "i {{location}}",
  },
  de: {
    withSublocation: "im {{location}} ({{sublocation}})",
    withoutSublocation: "im {{location}}",
  },
  es: {
    withSublocation: "en el {{location}} ({{sublocation}})",
    withoutSublocation: "en el {{location}}",
  },
  fi: {
    withSublocation: "{{location}}:ssa ({{sublocation}})",
    withoutSublocation: "{{location}}:ssa",
  },
  fr: {
    withSublocation: "dans le {{location}} ({{sublocation}})",
    withoutSublocation: "dans le {{location}}",
  },
  it: {
    withSublocation: "nel {{location}} ({{sublocation}})",
    withoutSublocation: "nel {{location}}",
  },
  nb: {
    withSublocation: "i {{location}} ({{sublocation}})",
    withoutSublocation: "i {{location}}",
  },
  nl: {
    withSublocation: "in de {{location}} ({{sublocation}})",
    withoutSublocation: "in de {{location}}",
  },
  pl: {
    withSublocation: "w {{location}} ({{sublocation}})",
    withoutSublocation: "w {{location}}",
  },
  pt: {
    withSublocation: "no {{location}} ({{sublocation}})",
    withoutSublocation: "no {{location}}",
  },
};

const ZERO_RESULTS: Record<string, string> = {
  sv: "Jag hittade ingen träff i lagret just nu. Vill du lägga till den?",
  en: "I couldn't find a match in the inventory right now. Would you like to add it?",
  da: "Jeg fandt intet match i lageret lige nu. Vil du tilføje det?",
  de: "Ich habe gerade keine Übereinstimmung im Lager gefunden. Möchtest du sie hinzufügen?",
  es: "No he encontrado ninguna coincidencia en la despensa ahora mismo. ¿Quieres añadirla?",
  fi: "En löytänyt osumaa varastosta juuri nyt. Haluatko lisätä sen?",
  fr: "Je n'ai trouvé aucune correspondance dans l'inventaire pour l'instant. Voulez-vous l'ajouter ?",
  it: "Non ho trovato corrispondenze in dispensa in questo momento. Vuoi aggiungerla?",
  nb: "Jeg fant ingen treff i lageret akkurat nå. Vil du legge det til?",
  nl: "Ik heb momenteel geen overeenkomst in de voorraad gevonden. Wil je het toevoegen?",
  pl: "Nie znalazłem teraz dopasowania w inwentarzu. Czy chcesz to dodać?",
  pt: "Não encontrei nenhuma correspondência na despensa de momento. Queres adicioná-la?",
};

const SINGLE_RESULT_PREFIX: Record<string, string> = {
  sv: "Jag hittade **{{name}}** {{location}}.",
  en: "I found **{{name}}** {{location}}.",
  da: "Jeg fandt **{{name}}** {{location}}.",
  de: "Ich habe **{{name}}** {{location}} gefunden.",
  es: "Encontré **{{name}}** {{location}}.",
  fi: "Löysin **{{name}}** {{location}}.",
  fr: "J'ai trouvé **{{name}}** {{location}}.",
  it: "Ho trovato **{{name}}** {{location}}.",
  nb: "Jeg fant **{{name}}** {{location}}.",
  nl: "Ik heb **{{name}}** {{location}} gevonden.",
  pl: "Znalazłem **{{name}}** {{location}}.",
  pt: "Encontrei **{{name}}** {{location}}.",
};

const MULTI_RESULT_PREFIX: Record<string, string> = {
  sv: "Jag hittade {{count}} saker som kan matcha:",
  en: "I found {{count}} things that could match:",
  da: "Jeg fandt {{count}} ting, der kan matche:",
  de: "Ich habe {{count}} Dinge gefunden, die passen könnten:",
  es: "Encontré {{count}} cosas que podrían coincidir:",
  fi: "Löysin {{count}} asiaa, jotka saattavat sopia:",
  fr: "J'ai trouvé {{count}} choses qui pourraient correspondre :",
  it: "Ho trovato {{count}} cose che potrebbero corrispondere:",
  nb: "Jeg fant {{count}} ting som kan matche:",
  nl: "Ik heb {{count}} dingen gevonden die kunnen overeenkomen:",
  pl: "Znalazłem {{count}} rzeczy, które mogą pasować:",
  pt: "Encontrei {{count}} coisas que podem corresponder:",
};

const MULTI_RESULT_SUFFIX: Record<string, string> = {
  sv: "Titta på listan nedan så ser du hur säker jag är på varje.",
  en: "Check the list below to see how sure I am about each one.",
  da: "Se listen nedenfor for at se, hvor sikker jeg er på hver enkelt.",
  de: "Sieh dir die Liste unten an, um zu sehen, wie sicher ich bei jedem Einzelnen bin.",
  es: "Mira la lista de abajo para ver qué tan seguro estoy de cada una.",
  fi: "Katso alla olevaa luetteloa nähdäksesi, kuinka varma olen kustakin.",
  fr: "Consulte la liste ci-dessous pour voir à quel point je suis sûr de chacun.",
  it: "Guarda l'elenco qui sotto per vedere quanto sono sicuro di ciascuno.",
  nb: "Se listen nedenfor for å se hvor sikker jeg er på hver enkelt.",
  nl: "Bekijk de onderstaande lijst om te zien hoe zeker ik van elk item ben.",
  pl: "Sprawdź listę poniżej, aby zobaczyć, jak pewny jestem każdej pozycji.",
  pt: "Vê a lista abaixo para veres o quão certo estou de cada uma.",
};

function resolve(catalog: Record<string, string>, languageTag: string): string {
  return catalog[lang(languageTag)] ?? catalog["en"] ?? catalog["sv"]!;
}

function formatLocation(item: SearchResultItem, languageTag: string): string {
  const templates = LOCATION_TEMPLATES[lang(languageTag)] ?? LOCATION_TEMPLATES["sv"]!;
  const tpl = item.sublocation ? templates.withSublocation : templates.withoutSublocation;
  if (!tpl) return "";
  return tpl
    .replace("{{location}}", item.locationName)
    .replace("{{sublocation}}", item.sublocation ?? "");
}

function formatSingle(item: SearchResultItem, languageTag: string): string {
  const prefix = resolve(SINGLE_RESULT_PREFIX, languageTag)
    .replace("{{name}}", item.displayName)
    .replace("{{location}}", formatLocation(item, languageTag));
  const hedge = resolve(TRUST_HEDGE[item.trustState], languageTag);
  return `${prefix} ${hedge}`;
}

function formatList(items: SearchResultItem[], languageTag: string): string {
  const l = lang(languageTag);
  const parts = items.map((item) => {
    const loc = formatLocation(item, languageTag);
    return `• ${item.displayName} ${loc}`;
  });
  const prefix = resolve(MULTI_RESULT_PREFIX, languageTag).replace(
    "{{count}}",
    String(items.length),
  );
  const suffix = resolve(MULTI_RESULT_SUFFIX, languageTag);
  return `${prefix}\n${parts.join("\n")}\n${suffix}`;
}

/**
 * Bygg ett naturligt-språkligt svar för fritextsökning i hushållslagret.
 * Ingen data fabriceras – allt som visas kommer från `items`.
 */
export function buildNaturalSearchResponse(items: SearchResultItem[], languageTag: string): string {
  if (items.length === 0) {
    return resolve(ZERO_RESULTS, languageTag);
  }
  if (items.length === 1) {
    return formatSingle(items[0]!, languageTag);
  }
  return formatList(items, languageTag);
}
