// components.jsx — UI primitives & sections

const PAGE_CONFIG = JSON.parse(document.getElementById('page-config').textContent);
const t = (text) => PAGE_CONFIG.translations?.[text] ?? text;
const localize = (value) => {
  if (typeof value === "string") return t(value);
  if (Array.isArray(value)) return value.map(localize);
  if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, localize(item)]));
  return value;
};

const useReveal = () => {
  React.useEffect(() => {
    const els = document.querySelectorAll(".reveal");
    if (!("IntersectionObserver" in window)) {
      els.forEach((el) => el.classList.add("is-visible"));
      return;
    }
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            e.target.classList.add("is-visible");
            io.unobserve(e.target);
          }
        });
      },
      { threshold: 0.12, rootMargin: "0px 0px -40px 0px" }
    );
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);
};

// ===== Nav =====
function Nav({ theme, onToggleTheme }) {
  const { userEmail, isAdmin, loginUrl, dashboardUrl, adminUrl, signOutUrl } = PAGE_CONFIG;
  return (
    <header className="nav">
      <div className="container nav-inner">
        <a className="brand" href="#top">
          <span className="brand-mark" aria-hidden="true"></span>
          <span className="brand-name">Nomia</span>
          <span className="brand-tag">MCP</span>
        </a>
        <nav className="nav-links" aria-label={t("Navigation principale")}>
          <a href="#tools">{t("Outils")}</a>
          <a href="#how">{t("Comment ça marche")}</a>
          <a href="#cases">{t("Cas d'usage")}</a>
          <a href="https://nomia.hyperping.app/" target="_blank" rel="noreferrer">{t("Statut")}</a>
        </nav>
        <div className="nav-cta">
          <a className="icon-btn language-switch" href={PAGE_CONFIG.language === "en" ? "/" : "/en/"} hrefLang={PAGE_CONFIG.language === "en" ? "fr" : "en"} lang={PAGE_CONFIG.language === "en" ? "fr" : "en"} aria-label={PAGE_CONFIG.language === "en" ? "Français" : "English"} title={PAGE_CONFIG.language === "en" ? "Français" : "English"}>{PAGE_CONFIG.language === "en" ? "FR" : "EN"}</a>
          <button className="icon-btn" onClick={onToggleTheme} aria-label={t("Basculer thème clair / sombre")} title={t("Thème")}>
            {theme === "dark" ? (
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="4" /><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" strokeLinecap="round" /></svg>
            ) : (
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79Z" strokeLinejoin="round" /></svg>
            )}
          </button>
          {userEmail ? (
            <>
              <a className="btn btn-sm btn-ghost" href={dashboardUrl}>{t("Mon tableau de bord")}</a>
              {isAdmin && <a className="btn btn-sm btn-ghost" href={adminUrl}>{t("Administration")}</a>}
              <form method="post" action={signOutUrl} style={{ display: "inline" }}>
                <button type="submit" className="btn btn-sm">{t("Déconnexion")}</button>
              </form>
            </>
          ) : (
            <>
              <a className="btn btn-sm btn-ghost" href={loginUrl}>{t("Se connecter")}</a>
              <a className="btn btn-sm btn-primary" href="#how">
                {t("Connecter à mon IA")}
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M5 12h14M13 5l7 7-7 7" strokeLinecap="round" strokeLinejoin="round" /></svg>
              </a>
            </>
          )}
        </div>
      </div>
    </header>
  );
}

// ===== Animated terminal (typing demo) =====
function HeroTerminal() {
  const SEQUENCES = React.useMemo(() => ([
    {
      label: "expert_search",
      lines: [
        { t: "comment", text: "// Claude appelle l'outil expert_search via MCP" },
        { t: "prompt", text: "→ tools/call expert_search" },
        { t: "json", text: '{ "query": "DN = 32016R0679", "language": "fr" }' },
        { t: "wait", ms: 600, text: "… requête EUR-Lex …" },
        { t: "ok", text: "✓ 200 OK · 1 résultat" },
        { t: "out", text: '{\n  "ok": true,\n  "data": {\n    "query": "DN = 32016R0679",\n    "total": 1, "page": 1,\n    "results": [{\n      "celex": "32016R0679",\n      "title": "Règlement (UE) 2016/679 du\n        Parlement européen et du Conseil\n        du 27 avril 2016 relatif à la\n        protection des personnes physiques\n        (règlement général sur la\n        protection des données)",\n      "url": "https://eur-lex.europa.eu/..."\n    }]\n  },\n  "error": null\n}' },
      ]
    },
    {
      label: "get_legal_text",
      lines: [
        { t: "comment", text: "// Récupération de l'article 6 du RGPD" },
        { t: "prompt", text: "→ tools/call get_legal_text" },
        { t: "json", text: '{ "celex": "32016R0679", "scope": "article", "article": "6" }' },
        { t: "wait", ms: 600, text: "… récupération du texte …" },
        { t: "ok", text: "✓ 200 OK · article 6" },
        { t: "out", text: '{\n  "ok": true,\n  "data": {\n    "celex": "32016R0679",\n    "scope": "article",\n    "article": {\n      "id": "art_6",\n      "heading": "Article 6",\n      "title": "Licéité du traitement",\n      "text": "1. Le traitement n\'est licite\n        que si au moins une des\n        conditions suivantes est remplie:\n        a) la personne concernée a\n        consenti au traitement;\n        b) le traitement est nécessaire\n        à l\'exécution d\'un contrat;\n        ..."\n    }\n  },\n  "error": null\n}' },
      ]
    },
    {
      label: "get_document_toc",
      lines: [
        { t: "comment", text: "// Table des matières du DSA (32022R2065)" },
        { t: "prompt", text: "→ tools/call get_document_toc" },
        { t: "json", text: '{ "celex": "32022R2065", "language": "fr" }' },
        { t: "wait", ms: 500, text: "… extraction TOC …" },
        { t: "ok", text: "✓ 200 OK · 93 articles · 5 chapitres" },
        { t: "out", text: '{\n  "ok": true,\n  "data": {\n    "celex": "32022R2065",\n    "toc": [\n      { "label": "CHAPITRE I",\n        "title": "DISPOSITIONS GÉNÉRALES" },\n      { "label": "CHAPITRE II",\n        "title": "RESPONSABILITÉ DES FOURNISSEURS" },\n      { "label": "CHAPITRE III",\n        "title": "OBLIGATIONS DE DILIGENCE" },\n      { "label": "CHAPITRE IV",\n        "title": "MISE EN ŒUVRE, COOPÉRATION" },\n      { "label": "CHAPITRE V",\n        "title": "DISPOSITIONS FINALES" }\n    ]\n  },\n  "error": null\n}' },
      ]
    }
  ]), []);

  const [tab, setTab] = React.useState(0);
  const [printed, setPrinted] = React.useState([]);
  const [typing, setTyping] = React.useState("");

  React.useEffect(() => {
    let cancelled = false;
    setPrinted([]);
    setTyping("");
    const seq = SEQUENCES[tab].lines.map((line) => ["comment", "wait", "ok"].includes(line.t) ? { ...line, text: t(line.text) } : line);

    async function run() {
      for (let i = 0; i < seq.length; i++) {
        if (cancelled) return;
        const line = seq[i];
        if (line.t === "wait") {
          setPrinted((p) => [...p, line]);
          await new Promise((r) => setTimeout(r, line.ms));
          continue;
        }
        const txt = line.text;
        for (let c = 0; c <= txt.length; c++) {
          if (cancelled) return;
          setTyping(txt.slice(0, c));
          await new Promise((r) => setTimeout(r, 6 + Math.random() * 8));
        }
        setPrinted((p) => [...p, line]);
        setTyping("");
        await new Promise((r) => setTimeout(r, line.t === "out" ? 1400 : 240));
      }
      await new Promise((r) => setTimeout(r, 2200));
      if (!cancelled) setTab((t) => (t + 1) % SEQUENCES.length);
    }
    run();
    return () => { cancelled = true; };
  }, [tab, SEQUENCES]);

  const renderLine = (line, key) => {
    if (line.t === "comment") return <span key={key} className="line tok-comment">{line.text}</span>;
    if (line.t === "prompt") return <span key={key} className="line"><span className="tok-prompt">{line.text}</span></span>;
    if (line.t === "json") return <span key={key} className="line tok-str">{line.text}</span>;
    if (line.t === "wait") return <span key={key} className="line tok-mute">{line.text}</span>;
    if (line.t === "ok") return <span key={key} className="line tok-ok">{line.text}</span>;
    if (line.t === "out") return <span key={key} className="line tok-key">{line.text}</span>;
    return null;
  };

  const live = (() => {
    const seq = SEQUENCES[tab].lines;
    const next = seq[printed.length];
    if (!next || next.t === "wait") return null;
    const cls =
      next.t === "comment" ? "tok-comment" :
      next.t === "prompt" ? "tok-prompt" :
      next.t === "json" ? "tok-str" :
      next.t === "ok" ? "tok-ok" :
      next.t === "out" ? "tok-key" : "";
    return <span className={"line " + cls}>{typing}<span className="cursor" /></span>;
  })();

  return (
    <div className="terminal" role="figure" aria-label={t("Démonstration du serveur MCP")}>
      <div className="terminal-bar">
        <div className="terminal-dots"><span /><span /><span /></div>
        <div className="terminal-title">claude · mcp · nomia</div>
        <div style={{ width: 36 }} />
      </div>
      <div className="terminal-tabs" role="tablist">
        {SEQUENCES.map((s, i) => (
          <button
            key={s.label}
            className={"terminal-tab" + (i === tab ? " is-active" : "")}
            onClick={() => setTab(i)}
            role="tab"
            aria-selected={i === tab}
          >
            {s.label}
          </button>
        ))}
      </div>
      <div className="terminal-body">
        {printed.map((l, i) => renderLine(l, i))}
        {live}
      </div>
    </div>
  );
}

// ===== Hero =====
function Hero() {
  const { domain, loginUrl } = PAGE_CONFIG;
  return (
    <section className="hero" id="top">
      <div className="container hero-grid">
        <div>
          <span className="hero-eyebrow fadein">
            <span className="pulse" />
            {t("Disponible ·")} {domain}
          </span>
          <h1 className="hero-title fadein delay-1">
            {t("La législation")} <em>{t("européenne")}</em>,<br />
            <span className="accent-bar" />{t("intégrée à votre IA.")}
          </h1>
          <p className="hero-sub fadein delay-2">
            {t("Nomia MCP branche Claude — et tout client compatible Model Context Protocol — directement sur la base de données juridiques EUR-Lex. Recherche experte, articles, considérants, table des matières : sans copier-coller, sans hallucination de référence.")}
          </p>
          <div className="hero-cta fadein delay-3">
            <a className="btn btn-primary btn-lg" href="#how">
              {t("Connecter à mon IA")}
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M5 12h14M13 5l7 7-7 7" strokeLinecap="round" strokeLinejoin="round" /></svg>
            </a>
            <a className="btn btn-lg" href={loginUrl}>
              <svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="M21.6 12.23c0-.74-.07-1.45-.2-2.13H12v4.03h5.4a4.6 4.6 0 0 1-2 3.02v2.51h3.23c1.89-1.74 2.97-4.31 2.97-7.43Z"/><path fill="currentColor" d="M12 22c2.7 0 4.96-.9 6.62-2.43l-3.23-2.5c-.9.6-2.05.96-3.39.96-2.6 0-4.81-1.76-5.6-4.13H3.07v2.6A10 10 0 0 0 12 22Z" opacity=".85"/><path fill="currentColor" d="M6.4 13.9a6 6 0 0 1 0-3.8V7.5H3.07a10 10 0 0 0 0 9l3.33-2.6Z" opacity=".55"/><path fill="currentColor" d="M12 5.96c1.47 0 2.79.5 3.83 1.5l2.86-2.86A10 10 0 0 0 12 2 10 10 0 0 0 3.07 7.5L6.4 10.1c.79-2.37 3-4.14 5.6-4.14Z" opacity=".7"/></svg>
              {t("Se connecter avec Google")}
            </a>
          </div>
        </div>
        <div className="fadein delay-2">
          <HeroTerminal />
        </div>
      </div>
      <div className="stars-ring" aria-hidden="true" />
    </section>
  );
}

// ===== Tools =====
function ToolsSection() {
  const [active, setActive] = React.useState(0);
  const tool = localize(window.TOOLS[active]);

  const formatJson = (v) =>
    typeof v === "string" ? v : JSON.stringify(v, null, 2);

  return (
    <section className="section" id="tools">
      <div className="container">
        <div className="section-head reveal">
          <div>
            <div className="section-num">{t("01 — Outils")}</div>
            <h2 className="section-title">{t("Six outils pour retrouver le droit à la source.")}</h2>
          </div>
          <p className="right">
            {t("Chaque outil renvoie un payload stable")} <code style={{ fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--ink)" }}>{"{ ok, data, error }"}</code>. {t("Tous sont")} <strong>read-only</strong> {t("— annotés")} <code style={{ fontFamily: "var(--font-mono)", fontSize: 13 }}>readOnlyHint: true</code>, <code style={{ fontFamily: "var(--font-mono)", fontSize: 13 }}>destructiveHint: false</code>. {t("Claude ne peut rien modifier sur EUR-Lex.")}
          </p>
        </div>

        <div className="tools reveal">
          <div className="tools-list" role="tablist" aria-label={t("Outils MCP")}>
            {localize(window.TOOLS).map((t, i) => (
              <button
                key={t.id}
                role="tab"
                aria-selected={i === active}
                className={"tool-row" + (i === active ? " is-active" : "")}
                onClick={() => setActive(i)}
              >
                <span className="tool-name">{t.name}</span>
                <span className="tool-blurb">{t.blurb}</span>
              </button>
            ))}
          </div>

          <div className="tool-detail">
            <div className="tool-detail-head">
              <h3>{tool.name}<span style={{ color: "var(--ink-4)" }}>()</span></h3>
              <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                <span className="tool-pill is-ok">read-only</span>
                <span className="tool-pill">{"JSON · { ok, data, error }"}</span>
              </div>
            </div>

            <p className="desc">{tool.description}</p>

            <div>
              <div className="section-num" style={{ marginBottom: 12 }}>{t("Paramètres")}</div>
              <div className="tool-args">
                {tool.args.map((a) => (
                  <div className="arg-row" key={a.name}>
                    <span>
                      <span className="arg-name">{a.name}</span>
                      <span className="arg-type"> · {a.type}</span>
                    </span>
                    <span className="arg-desc">{a.desc}</span>
                  </div>
                ))}
              </div>
            </div>

            <div className="terminal" style={{ marginTop: 8 }}>
              <div className="terminal-bar">
                <div className="terminal-dots"><span /><span /><span /></div>
                <div className="terminal-title">{tool.name} — {t("exemple")}</div>
                <div style={{ width: 36 }} />
              </div>
              <div className="terminal-body">
                <span className="line tok-comment">{t("// requête")}</span>
                <span className="line tok-str">{tool.sample.input}</span>
                <span className="line tok-mute">{"\n"}</span>
                <span className="line tok-comment">{t("// réponse")}</span>
                <span className="line tok-key">{formatJson(tool.sample.output)}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ===== How it works =====
function HowItWorks() {
  const guideRef = React.useRef(null);
  React.useEffect(() => {
    let mounted = true;
    let dispose;
    import("/static/installation-guide.js").then(({ activateInstallationGuide }) => {
      if (mounted) dispose = activateInstallationGuide(guideRef.current?.querySelector("[data-installation-guide]"));
    }).catch(() => {
      // The rendered instructions and documentation links remain available.
    });
    return () => {
      mounted = false;
      dispose?.();
    };
  }, []);
  return (
    <section className="section" id="how">
      <div className="container">
        <div className="section-head reveal">
          <div>
            <div className="section-num">{t("02 — Mise en route")}</div>
            <h2 className="section-title">{t("Connectez votre assistant, sans clé API.")}</h2>
          </div>
          <p className="right">
            {t("Choisissez votre outil et sa version pour afficher la marche à suivre. L’autorisation se fait avec votre compte Google ; Nomia consulte les sources en lecture seule.")}
          </p>
        </div>
        <div ref={guideRef} dangerouslySetInnerHTML={{ __html: PAGE_CONFIG.installationGuideHtml }} />
      </div>
    </section>
  );
}

// ===== Use cases =====
function UseCases() {
  return (
    <section className="section" id="cases">
      <div className="container">
        <div className="section-head reveal">
          <div>
            <div className="section-num">{t("03 — Cas d'usage")}</div>
            <h2 className="section-title">{t("Pour les juristes qui veulent du texte exact, pas un résumé approximatif.")}</h2>
          </div>
          <p className="right">
            {t("Nomia MCP s'adresse aux avocats, fiscalistes, juristes d'entreprise et chercheurs qui travaillent sur le droit européen au quotidien — et qui ne peuvent pas se permettre une référence inventée.")}
          </p>
        </div>

        <div className="cases">
          {localize(window.USE_CASES).map((c, i) => (
            <div className="case reveal" key={c.tag} style={{ transitionDelay: `${(i % 2) * 80}ms` }}>
              <div className="case-tag">{c.tag}</div>
              <h4>{c.title}</h4>
              <p>{c.body}</p>
              <div className="case-prompt">{c.prompt}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ===== Footer =====
function Footer() {
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer-grid">
          <div>
            <a className="brand" href="#top">
              <span className="brand-mark" aria-hidden="true"></span>
              <span className="brand-name">Nomia</span>
              <span className="brand-tag">MCP</span>
            </a>
            <p style={{ color: "var(--ink-3)", fontSize: 14, marginTop: 14, maxWidth: "44ch", lineHeight: 1.55 }}>
              {t("Serveur Model Context Protocol open-source pour interroger la base juridique EUR-Lex depuis Claude et tout client MCP compatible.")}
            </p>
          </div>
          <div>
            <h5>{t("Mentions")}</h5>
            <ul>
              <li><a href="https://eur-lex.europa.eu/content/legal-notice/legal-notice.html" target="_blank" rel="noreferrer">{t("Données EUR-Lex")}</a></li>
              <li><a href="#" target="_blank" rel="noreferrer">{t("Politique de confidentialité")}</a></li>
            </ul>
          </div>
        </div>
        <div className="footer-end">
          <span>{t("© 2026 Nomia MCP · Service indépendant, non affilié à l'Office des publications de l'UE.")}</span>
          <a className="status-pill" href="https://nomia.hyperping.app/" target="_blank" rel="noreferrer">
            <span className="dot" />{t("Voir le statut du service")}
          </a>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, {
  Nav, Hero, ToolsSection, HowItWorks, UseCases, Footer, useReveal, HeroTerminal
});
