/* MyAds. — Blog Composer (self-service article injection) · #blog-admin */
const { useState: useStateAdmin, useMemo: useMemoAdmin, useEffect: useEffectAdmin } = React;

/* bilingual micro-helper (nl falls back to fr) */
const aTr = (lang) => (fr, en) => (lang === "en" ? en : fr);

function slugify(s) {
  return (s || "")
    .toLowerCase()
    .normalize("NFD").replace(/[\u0300-\u036f]/g, "")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .slice(0, 80);
}

function emptyLoc() {
  return { title: "", excerpt: "", tags: "", read: 5, body: "" };
}

function blankForm() {
  return {
    slug: "",
    slugTouched: false,
    category: "industry",
    date: new Date().toISOString().slice(0, 10),
    authorName: "MyAds Team",
    authorRole: "Rédaction",
    cover: "",
    enNl: false,
    enEn: false,
    fr: emptyLoc(),
    nl: emptyLoc(),
    en: emptyLoc(),
  };
}

/* convert a stored post -> form shape */
function postToForm(p) {
  const f = blankForm();
  f.slug = p.slug || "";
  f.slugTouched = true;
  f.category = p.category || "industry";
  f.date = p.date || f.date;
  f.authorName = (p.author && p.author.name) || "MyAds Team";
  f.authorRole = (p.author && p.author.role) || "";
  f.cover = p.cover || "";
  ["fr", "nl", "en"].forEach((lc) => {
    if (p[lc]) {
      f[lc] = {
        title: p[lc].title || "",
        excerpt: p[lc].excerpt || "",
        tags: (p[lc].tags || []).join(", "),
        read: p[lc].read || 5,
        body: p[lc].body || "",
      };
    }
  });
  f.enNl = !!p.nl;
  f.enEn = !!p.en;
  return f;
}

/* convert a form -> stored post (throws on invalid) */
function formToPost(f) {
  const slug = slugify(f.slug || f.fr.title);
  if (!slug) throw new Error("Un slug (ou un titre FR) est requis.");
  if (!f.fr.title.trim()) throw new Error("Le titre FR est requis.");
  if (!f.fr.body.trim()) throw new Error("Le contenu FR est requis.");

  const loc = (b) => ({
    title: b.title.trim(),
    excerpt: b.excerpt.trim(),
    tags: b.tags.split(",").map((t) => t.trim()).filter(Boolean),
    read: Math.max(1, parseInt(b.read, 10) || 1),
    body: b.body,
  });

  const post = {
    slug,
    category: f.category,
    date: f.date,
    author: { name: f.authorName.trim() || "MyAds Team", role: f.authorRole.trim(), avatar: "" },
    cover: f.cover.trim(),
    fr: loc(f.fr),
  };
  if (f.enNl && f.nl.title.trim()) post.nl = loc(f.nl);
  if (f.enEn && f.en.title.trim()) post.en = loc(f.en);
  return post;
}

function BlogAdmin({ lang }) {
  const tr = aTr(lang);
  const cats = window.MYADS_BLOG_CATEGORIES.fr; // composer authored in FR keys
  const [form, setForm] = useStateAdmin(blankForm);
  const [list, setList] = useStateAdmin(() => window.MyAdsBlog.list());
  const [tab, setTab] = useStateAdmin("fr");
  const [toast, setToast] = useStateAdmin(null);
  const [showIO, setShowIO] = useStateAdmin(false);
  const [ioText, setIoText] = useStateAdmin("");

  const fileCount = (window.MYADS_BLOG_FILE_POSTS || []).length;
  const editing = useMemoAdmin(
    () => form.slugTouched && list.some((p) => p.slug === slugify(form.slug)),
    [form.slug, form.slugTouched, list]
  );

  const flash = (m, kind) => {
    setToast({ m, kind: kind || "ok" });
    window.clearTimeout(flash._t);
    flash._t = window.setTimeout(() => setToast(null), 3200);
  };

  const set = (patch) => setForm((f) => ({ ...f, ...patch }));
  const setLoc = (lc, patch) => setForm((f) => ({ ...f, [lc]: { ...f[lc], ...patch } }));

  const onTitleFr = (v) =>
    setForm((f) => ({
      ...f,
      fr: { ...f.fr, title: v },
      slug: f.slugTouched ? f.slug : slugify(v),
    }));

  const reset = () => {
    setForm(blankForm());
    setTab("fr");
  };

  const save = () => {
    try {
      const post = formToPost(form);
      window.MyAdsBlog.save(post);
      setList(window.MyAdsBlog.list());
      flash(tr("Article enregistré — visible sur le blog.", "Article saved — live on the blog."));
      setForm((f) => ({ ...f, slugTouched: true }));
    } catch (e) {
      flash(e.message, "err");
    }
  };

  const edit = (slug) => {
    const p = window.MyAdsBlog.list().find((x) => x.slug === slug);
    if (p) {
      setForm(postToForm(p));
      setTab("fr");
      window.scrollTo({ top: 0, behavior: "smooth" });
    }
  };

  const del = (slug) => {
    window.MyAdsBlog.remove(slug);
    setList(window.MyAdsBlog.list());
    if (slugify(form.slug) === slug) reset();
    flash(tr("Article supprimé.", "Article deleted."));
  };

  const doExport = () => {
    setIoText(window.MyAdsBlog.export());
    setShowIO(true);
  };
  const doImport = () => {
    try {
      const n = window.MyAdsBlog.import(ioText);
      setList(window.MyAdsBlog.list());
      setShowIO(false);
      flash(tr(`${n} article(s) importé(s).`, `${n} article(s) imported.`));
    } catch (e) {
      flash(e.message, "err");
    }
  };
  const copyExport = () => {
    navigator.clipboard?.writeText(ioText);
    flash(tr("Copié dans le presse-papiers.", "Copied to clipboard."));
  };

  const locBlock = (lc, optional) => {
    const b = form[lc];
    return (
      <div className="ba-loc">
        <div className="ba-field">
          <label>{tr("Titre", "Title")}{lc === "fr" ? " *" : ""}</label>
          <input
            className="cf-input"
            value={b.title}
            onChange={(e) => (lc === "fr" ? onTitleFr(e.target.value) : setLoc(lc, { title: e.target.value }))}
            placeholder={tr("Titre de l'article", "Article title")}
          />
        </div>
        <div className="ba-field">
          <label>{tr("Résumé (carte)", "Excerpt (card)")}</label>
          <textarea
            className="cf-input"
            rows={2}
            value={b.excerpt}
            onChange={(e) => setLoc(lc, { excerpt: e.target.value })}
            placeholder={tr("Phrase d'accroche affichée sur la carte.", "Teaser shown on the card.")}
          />
        </div>
        <div className="ba-row2">
          <div className="ba-field">
            <label>{tr("Tags (séparés par des virgules)", "Tags (comma-separated)")}</label>
            <input
              className="cf-input"
              value={b.tags}
              onChange={(e) => setLoc(lc, { tags: e.target.value })}
              placeholder="CTV, Video, Belgique"
            />
          </div>
          <div className="ba-field ba-field-sm">
            <label>{tr("Lecture (min)", "Read (min)")}</label>
            <input
              className="cf-input"
              type="number"
              min="1"
              value={b.read}
              onChange={(e) => setLoc(lc, { read: e.target.value })}
            />
          </div>
        </div>
        <div className="ba-field">
          <label>{tr("Contenu — markdown", "Content — markdown")}{lc === "fr" ? " *" : ""}</label>
          <textarea
            className="cf-input ba-body"
            rows={14}
            value={b.body}
            onChange={(e) => setLoc(lc, { body: e.target.value })}
            placeholder={"# Titre\n\nParagraphe en **markdown**.\n\n## Sous-titre\n\n- point un\n- point deux\n\n> Une citation."}
          />
        </div>
      </div>
    );
  };

  // live preview uses the FR block (or active tab if filled)
  const pv = form[tab].title || form[tab].body ? form[tab] : form.fr;
  const pvTags = pv.tags.split(",").map((t) => t.trim()).filter(Boolean);
  const MDc = window.MD;

  return (
    <main className="blog-page ba-page">
      <section className="blog-hero ba-hero" data-screen-label="Blog Composer">
        <div className="container">
          <a href="#blog" className="blog-back">← {tr("Retour au blog", "Back to blog")}</a>
          <div className="kicker">{tr("ESPACE RÉDACTION", "EDITOR")}</div>
          <h1 className="blog-h1">{tr("Composer", "Composer")} <em>{tr("un article", "an article")}.</em></h1>
          <p className="blog-sub">
            {tr(
              "Rédigez et publiez de nouveaux articles au fur et à mesure. Ils sont enregistrés dans ce navigateur et apparaissent immédiatement sur le blog. Exportez-les en JSON pour les rendre permanents.",
              "Write and publish new articles over time. They are stored in this browser and appear on the blog immediately. Export them as JSON to make them permanent."
            )}
          </p>
        </div>
      </section>

      <section className="ba-shell section-pad">
        <div className="container ba-grid">
          {/* ---------- Editor ---------- */}
          <div className="ba-editor">
            <div className="ba-card">
              <div className="ba-card-head">
                <h3>{editing ? tr("Modifier l'article", "Edit article") : tr("Nouvel article", "New article")}</h3>
                {editing && <span className="ba-badge-edit">{tr("édition", "editing")}</span>}
              </div>

              <div className="ba-row2">
                <div className="ba-field">
                  <label>{tr("Catégorie", "Category")}</label>
                  <select className="cf-input" value={form.category} onChange={(e) => set({ category: e.target.value })}>
                    {Object.entries(cats).filter(([k]) => k !== "all").map(([k, lbl]) => (
                      <option key={k} value={k}>{lbl}</option>
                    ))}
                  </select>
                </div>
                <div className="ba-field ba-field-sm">
                  <label>{tr("Date", "Date")}</label>
                  <input className="cf-input" type="date" value={form.date} onChange={(e) => set({ date: e.target.value })} />
                </div>
              </div>

              <div className="ba-row2">
                <div className="ba-field">
                  <label>{tr("Auteur", "Author")}</label>
                  <input className="cf-input" value={form.authorName} onChange={(e) => set({ authorName: e.target.value })} />
                </div>
                <div className="ba-field">
                  <label>{tr("Rôle", "Role")}</label>
                  <input className="cf-input" value={form.authorRole} onChange={(e) => set({ authorRole: e.target.value })} />
                </div>
              </div>

              <div className="ba-row2">
                <div className="ba-field">
                  <label>Slug (URL)</label>
                  <input
                    className="cf-input"
                    value={form.slug}
                    onChange={(e) => set({ slug: e.target.value, slugTouched: true })}
                    placeholder="mon-article"
                  />
                </div>
                <div className="ba-field">
                  <label>{tr("Image de couverture (URL, option.)", "Cover image (URL, optional)")}</label>
                  <input className="cf-input" value={form.cover} onChange={(e) => set({ cover: e.target.value })} placeholder="https://…" />
                </div>
              </div>

              {/* language tabs */}
              <div className="ba-langtabs">
                <button className={"ba-langtab" + (tab === "fr" ? " active" : "")} onClick={() => setTab("fr")}>FR</button>
                {form.enNl && <button className={"ba-langtab" + (tab === "nl" ? " active" : "")} onClick={() => setTab("nl")}>NL</button>}
                {form.enEn && <button className={"ba-langtab" + (tab === "en" ? " active" : "")} onClick={() => setTab("en")}>EN</button>}
                <div className="ba-langadd">
                  <label className={form.enNl ? "on" : ""}>
                    <input type="checkbox" checked={form.enNl} onChange={(e) => { set({ enNl: e.target.checked }); if (!e.target.checked && tab === "nl") setTab("fr"); }} /> + NL
                  </label>
                  <label className={form.enEn ? "on" : ""}>
                    <input type="checkbox" checked={form.enEn} onChange={(e) => { set({ enEn: e.target.checked }); if (!e.target.checked && tab === "en") setTab("fr"); }} /> + EN
                  </label>
                </div>
              </div>

              {tab === "fr" && locBlock("fr")}
              {tab === "nl" && form.enNl && locBlock("nl", true)}
              {tab === "en" && form.enEn && locBlock("en", true)}

              <div className="ba-actions">
                <button className="btn btn-accent btn-sm" onClick={save}>
                  {editing ? tr("Mettre à jour", "Update") : tr("Publier l'article", "Publish article")} <span className="arrow">→</span>
                </button>
                <button className="btn btn-secondary btn-sm" onClick={reset}>{tr("Nouveau / Réinitialiser", "New / Reset")}</button>
                <div className="ba-spacer" />
                <button className="btn btn-ghost btn-sm" onClick={doExport}>{tr("Exporter / Importer JSON", "Export / Import JSON")}</button>
              </div>
            </div>

            {/* existing browser articles */}
            <div className="ba-card">
              <div className="ba-card-head">
                <h3>{tr("Articles enregistrés ici", "Articles stored here")} <span className="ba-count">{list.length}</span></h3>
              </div>
              {list.length === 0 ? (
                <p className="ba-muted">{tr("Aucun article pour l'instant. Rédigez le premier ci-dessus.", "No articles yet. Write the first one above.")}</p>
              ) : (
                <div className="ba-list">
                  {[...list].sort((a, b) => (b.date || "").localeCompare(a.date || "")).map((p) => (
                    <div key={p.slug} className="ba-item">
                      <div className="ba-item-main">
                        <div className="ba-item-title">{(p.fr || p.en || p.nl || {}).title || p.slug}</div>
                        <div className="ba-item-meta">
                          <span className="ba-tagcat">{cats[p.category] || p.category}</span>
                          <span>· {p.date}</span>
                          <span>· /{p.slug}</span>
                          {p.nl && <span className="ba-lc">NL</span>}
                          {p.en && <span className="ba-lc">EN</span>}
                        </div>
                      </div>
                      <div className="ba-item-act">
                        <a className="ba-link" href={"#blog/" + p.slug}>{tr("voir", "view")}</a>
                        <button className="ba-link" onClick={() => edit(p.slug)}>{tr("éditer", "edit")}</button>
                        <button className="ba-link ba-del" onClick={() => del(p.slug)}>{tr("supprimer", "delete")}</button>
                      </div>
                    </div>
                  ))}
                </div>
              )}
              {fileCount > 0 && (
                <p className="ba-muted ba-filenote">
                  {tr(
                    `${fileCount} article(s) intégré(s) au site (non éditables ici).`,
                    `${fileCount} article(s) baked into the site (not editable here).`
                  )}
                </p>
              )}
            </div>
          </div>

          {/* ---------- Live preview ---------- */}
          <aside className="ba-preview">
            <div className="ba-preview-sticky">
              <div className="ba-preview-label">{tr("Aperçu en direct", "Live preview")}</div>
              <div className="ba-preview-card">
                <div className="article-meta-top">
                  <span className="post-cat">{cats[form.category] || form.category}</span>
                  <span className="post-dot">·</span>
                  <span>{form.date}</span>
                  <span className="post-dot">·</span>
                  <span>{pv.read} min</span>
                </div>
                <h1 className="article-title ba-pv-title">{pv.title || tr("Titre de l'article", "Article title")}</h1>
                {pv.excerpt && <p className="article-excerpt">{pv.excerpt}</p>}
                <div className="ba-pv-author">
                  <span className="author-avatar" style={{ background: "var(--accent)" }}>
                    {(form.authorName || "M").split(" ").map((s) => s[0]).slice(0, 2).join("").toUpperCase()}
                  </span>
                  <div>
                    <div className="pa-name">{form.authorName}</div>
                    <div className="pa-role">{form.authorRole}</div>
                  </div>
                </div>
                <div className="ba-pv-body article-body">
                  {MDc ? <MDc source={pv.body} /> : <pre>{pv.body}</pre>}
                </div>
                {pvTags.length > 0 && (
                  <div className="article-tags">
                    {pvTags.map((tg) => <span key={tg} className="tag">#{tg}</span>)}
                  </div>
                )}
              </div>
            </div>
          </aside>
        </div>
      </section>

      {/* Export / Import drawer */}
      {showIO && (
        <div className="ba-modal-overlay" onClick={() => setShowIO(false)}>
          <div className="ba-modal" onClick={(e) => e.stopPropagation()}>
            <button className="modal-close" onClick={() => setShowIO(false)} aria-label="close">×</button>
            <h3>{tr("Exporter / Importer", "Export / Import")}</h3>
            <p className="ba-muted">
              {tr(
                "Copiez ce JSON pour sauvegarder vos articles ou les rendre permanents (à coller dans MYADS_BLOG_FILE_POSTS). Vous pouvez aussi coller un JSON ici puis Importer pour remplacer les articles de ce navigateur.",
                "Copy this JSON to back up your articles or make them permanent (paste into MYADS_BLOG_FILE_POSTS). You can also paste JSON here then Import to replace this browser's articles."
              )}
            </p>
            <textarea className="cf-input ba-io" rows={14} value={ioText} onChange={(e) => setIoText(e.target.value)} spellCheck={false} />
            <div className="ba-actions">
              <button className="btn btn-accent btn-sm" onClick={copyExport}>{tr("Copier", "Copy")}</button>
              <button className="btn btn-secondary btn-sm" onClick={doImport}>{tr("Importer (remplace)", "Import (replaces)")}</button>
            </div>
          </div>
        </div>
      )}

      {toast && <div className={"ba-toast " + (toast.kind === "err" ? "err" : "ok")}>{toast.m}</div>}
    </main>
  );
}

Object.assign(window, { BlogAdmin });
