// ============================================================================
// i18n — English / Spanish translation layer for Black Craft
// Dictionary keyed by section. Names (Charlie, Mabu, Black Craft, version
// strings) and internal image placeholders are intentionally NOT translated.
// ============================================================================
const { createContext: createI18nContext, useContext: useI18nContext } = React;

const DICT = {
  en: {
    code: "en",
    nav: { game: "The Game", team: "The Team", devlog: "Devlog" },
    hero: {
      subtitle:
        "A 2D toon survival RPG. Build a home, raid the dungeon, and try not to wake the things sleeping down there.",
      tags: ["Survival RPG", "Dungeon Crawler", "Base Building", "Single-Player"],
      ctaWishlist: "Wishlist on Steam",
      ctaSee: "See the Game",
      rune1: "Day 41. The compass spins anti-clockwise now. We took it as decoration. It was a warning.",
      rune2: "The bottles catch a wind no draught makes. The bubbles always rise toward whatever is watching.",
    },
    game: {
      label: "The Game",
      title1: "Build by day.",
      title2: "Dig by night.",
      lede: "Dimension Disrupt is a 2D toon survival RPG with dungeon-crawler combat and base-building roots. Made by two people. Drawn by hand.",
      pillarWord: "PILLAR",
      pillars: [
        { title: "Survive", copy: "Hunger. Cold. Sanity. Whatever's in the cupboard. The world only pretends to sit still while you sleep." },
        { title: "Disrupt", copy: "Procedural dungeons that hold a grudge. Loot is a polite word for what you bring back up." },
        { title: "Build", copy: "Workshop, garden, shrine, fence. Decide what to put near the door — something out there is taking notes." },
      ],
      featuresLabel: "Features",
      features: [
        { t: "Hand-drawn, hand-animated", c: "Every leaf, lantern and lurking horror toon-shaded frame by frame." },
        { t: "Sanity is a stat", c: "See too much, lose the thread. Your character will start to lie to you. The UI joins in eventually." },
        { t: "Dimensions, plural", c: "Five worlds bleed through one map. Find the seams. Don't pull on them." },
        { t: "A base that's yours", c: "Modular building, tools and traps. Lay it out, light it up, lock it down." },
        { t: "Pets that pull weight", c: "Companions that fight, fetch, and occasionally judge your choices." },
      ],
      rune: "The first thing the dungeon takes is your shadow. The second is your name. The third is negotiable.",
    },
    studio: {
      label: "The Team",
      title1: "Two people.",
      title2: "One small studio.",
      lede: "Black Craft is Charlie and Mabu. We work from our home, on our own hours, with our own pets at our feet.",
      mainsK: "MAINS",
      fearsK: "FEARS",
      members: [
        {
          role: "Developer · Technical Artist",
          bio: "Writes the code, builds the tools, teaches sprites to behave. Charlie keeps the engine humming.",
          mains: "Engine, tools",
          fears: "French lawyers",
        },
        {
          role: "Artist · Animator · Writer",
          bio: "Draws everything you see and writes everything you read. Painstakingly animates hand-drawn sprites, the old school way.",
          mains: "Art, anim, narrative",
          fears: "Blank pages",
        },
      ],
      rune: "Mabu's first drawing of the protagonist had four eyes. Charlie said no. Mabu compromised at three. Two are usually closed.",
    },
    devlog: {
      label: "Devlog",
      title1: "Notes from",
      title2: "the desk.",
      all: "All Entries",
      posts: [
        { tag: "Patchwork", title: "Stitching a dungeon that remembers you", excerpt: "On procedural dungeons that aren't actually procedural — how rooms carry grudges between runs, and why we let the map keep a diary." },
        { tag: "Art", title: "Sixty frames of one nervous slime", excerpt: "Mabu walks through the wobble-to-burst animation pipeline." },
        { tag: "Build", title: "Sanity, the worst stat we've ever shipped", excerpt: "Lies, hallucinations, and the UI elements that fight back." },
      ],
      rune: "The dungeon was supposed to forget. We left the variable in. We are leaving it in.",
    },
    support: {
      label: "Supported by",
      blurb: "Demo development backed by ACAU's 2024 Videogame Development grant — strengthening Uruguay's audiovisual sector.",
    },
    footer: {
      tagline: "A two-person studio making small, stubborn games. Currently making Dimension Disrupt.",
      colGame: { title: "The Game", links: ["Pillars", "Features", "Press Kit", "Wishlist"] },
      colStudio: { title: "Studio", links: ["About", "Devlog", "Contact"] },
      colFollow: { title: "Follow", links: ["Twitter / X", "Bluesky", "Discord", "Mailing list"] },
      copyright: "© 2026 Black Craft",
    },
  },

  es: {
    code: "es",
    nav: { game: "El Juego", team: "El Equipo", devlog: "Diario" },
    hero: {
      subtitle:
        "Un RPG de supervivencia toon en 2D. Construye un hogar, saquea la mazmorra e intenta no despertar a las cosas que duermen ahí abajo.",
      tags: ["Supervivencia", "Exploración", "Construcción de Base", "1 Jugador"],
      ctaWishlist: "Añadir a deseados en Steam",
      ctaSee: "Ver el Juego",
      rune1: "Día 41. La brújula ahora gira en sentido antihorario. La tomamos por decoración. Era una advertencia.",
      rune2: "Las botellas atrapan un viento que ninguna corriente produce. Las burbujas siempre suben hacia lo que sea que esté observando.",
    },
    game: {
      label: "El Juego",
      title1: "Construye de día.",
      title2: "Excava de noche.",
      lede: "Dimension Disrupt es un RPG de supervivencia toon en 2D con combate, construcción de bases y exploración de distintas dimensiones. Hecho por dos personas. Dibujado a mano.",
      pillarWord: "PILAR",
      pillars: [
        { title: "Sobrevive", copy: "Hambre. Frío. Cordura. Lo que sea que haya en la alacena. El mundo solo finge quedarse quieto mientras duermes." },
        { title: "Altera", copy: "Dimensiones que guardan rencor. «Botín» es una palabra educada para lo que logras traer de vuelta." },
        { title: "Construye", copy: "Taller, jardín, santuario, valla. Decide qué poner cerca de la puerta: algo allá afuera está tomando notas." },
      ],
      featuresLabel: "Características",
      features: [
        { t: "Dibujado y animado a mano", c: "Cada hoja, linterna y horror al acecho sombreado en estilo toon, fotograma a fotograma." },
        { t: "La cordura es una estadística", c: "Si ves demasiado, pierdes el hilo. Tu personaje empezará a mentirte. La interfaz acabará por unirse." },
        { t: "Dimensiones, en plural", c: "Cinco mundos se filtran a través de un solo mapa. Encuentra las costuras. No tires de ellas." },
        { t: "Una base que es tuya", c: "Construcción modular, herramientas y trampas. Distribúyela, ilumínala, asegúrala." },
        { t: "Mascotas que aportan", c: "Compañeros que luchan, recogen cosas y, de vez en cuando, juzgan tus decisiones." },
      ],
      rune: "Lo primero que la mazmorra te quita es tu sombra. Lo segundo, tu nombre. Lo tercero es negociable.",
    },
    studio: {
      label: "El Equipo",
      title1: "Dos personas.",
      title2: "Un pequeño estudio.",
      lede: "Black Craft son Charlie y Mabu. Trabajamos desde casa, con nuestros propios horarios y con nuestras mascotas a los pies.",
      mainsK: "DOMINA",
      fearsK: "TEME",
      members: [
        {
          role: "Desarrollador · Artista Técnico",
          bio: "Escribe el código, crea las herramientas y enseña a los sprites a comportarse. Charlie mantiene el motor en marcha.",
          mains: "Motor, herramientas",
          fears: "Abogados franceses",
        },
        {
          role: "Artista · Animadora · Escritora",
          bio: "Dibuja todo lo que ves y escribe todo lo que lees. Anima minuciosamente sprites dibujados a mano, a la vieja usanza.",
          mains: "Arte, animación, narrativa",
          fears: "Páginas en blanco",
        },
      ],
      rune: "El primer dibujo de Mabu del protagonista tenía cuatro ojos. Charlie dijo que no. Mabu transigió con tres. Dos suelen estar cerrados.",
    },
    devlog: {
      label: "Diario",
      title1: "Notas",
      title2: "de desarrollo.",
      all: "Todas las Entradas",
      posts: [
        { tag: "Remiendos", title: "Cosiendo una mazmorra que te recuerda", excerpt: "Sobre mazmorras procedurales que en realidad no lo son: cómo las salas guardan rencor entre partidas y por qué dejamos que el mapa lleve un diario." },
        { tag: "Arte", title: "Sesenta fotogramas de un slime nervioso", excerpt: "Mabu repasa el proceso de animación, del temblor al estallido." },
        { tag: "Construcción", title: "La cordura, la peor estadística que hemos lanzado", excerpt: "Mentiras, alucinaciones y los elementos de interfaz que se resisten." },
      ],
      rune: "La mazmorra debía olvidar. Dejamos la variable. La vamos a dejar.",
    },
    support: {
      label: "Apoyado por",
      blurb: "Desarrollo de la demo apoyado por la convocatoria Desarrollo de Videojuegos 2024 de ACAU — fortaleciendo el sector audiovisual uruguayo.",
    },
    footer: {
      tagline: "Un estudio de dos personas que hace juegos pequeños y tercos. Actualmente desarrollando Dimension Disrupt.",
      colGame: { title: "El Juego", links: ["Pilares", "Características", "Kit de Prensa", "Lista de Deseados"] },
      colStudio: { title: "Estudio", links: ["Acerca de", "Devlog", "Contacto"] },
      colFollow: { title: "Síguenos", links: ["Twitter / X", "Bluesky", "Discord", "Lista de correo"] },
      copyright: "© 2026 Black Craft",
    },
  },
};

const LANGS = [
  { code: "en", short: "EN", label: "English", flag: "https://flagcdn.com/gb.svg" },
  { code: "es", short: "ES", label: "Español", flag: "https://flagcdn.com/es.svg" },
];

const LangContext = createI18nContext({ lang: "en", t: DICT.en, setLang: () => {} });

const LANG_STORAGE_KEY = "blackcraft.lang";

function LanguageProvider({ children }) {
  const [lang, setLangState] = React.useState(() => {
    try {
      const saved = localStorage.getItem(LANG_STORAGE_KEY);
      if (saved && DICT[saved]) return saved;
    } catch (e) {}
    // fall back to browser preference, default English
    const nav = (navigator.language || "en").slice(0, 2).toLowerCase();
    return DICT[nav] ? nav : "en";
  });

  const setLang = React.useCallback((next) => {
    if (!DICT[next]) return;
    setLangState(next);
    try { localStorage.setItem(LANG_STORAGE_KEY, next); } catch (e) {}
  }, []);

  React.useEffect(() => {
    document.documentElement.lang = lang;
  }, [lang]);

  const value = { lang, setLang, t: DICT[lang] };
  return <LangContext.Provider value={value}>{children}</LangContext.Provider>;
}

function useLang() {
  return useI18nContext(LangContext);
}

// ===== Language picker — flag dropdown =====
function LangPicker() {
  const { lang, setLang } = useLang();
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  const current = LANGS.find((l) => l.code === lang) || LANGS[0];

  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  return (
    <div className={`lang-picker ${open ? "open" : ""}`} ref={ref}>
      <button
        type="button"
        className="lang-current"
        aria-haspopup="listbox"
        aria-expanded={open}
        aria-label="Language / Idioma"
        onClick={() => setOpen((o) => !o)}>
        <img className="flag" src={current.flag} alt="" width="22" height="15" />
        <span className="lang-code">{current.short}</span>
        <svg className="chev" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
          <path d="M6 9l6 6 6-6" />
        </svg>
      </button>
      {open &&
        <ul className="lang-menu" role="listbox">
          {LANGS.map((l) =>
            <li
              key={l.code}
              role="option"
              aria-selected={l.code === lang}
              className={`lang-item ${l.code === lang ? "active" : ""}`}
              onClick={() => { setLang(l.code); setOpen(false); }}>
              <img className="flag" src={l.flag} alt="" width="22" height="15" />
              <span className="lang-name">{l.label}</span>
            </li>
          )}
        </ul>
      }
    </div>);
}

Object.assign(window, { DICT, LANGS, LanguageProvider, useLang, LangPicker });
