// DeepDiveArticle — the /deep-dive/{slug} route.
//
// The dossier itself is window.ESSAYS_FULL[slug] (a committed essay_<slug>.js
// file with series:"deep-dive"); this wrapper only enforces the publish gate
// and renders it through the SAME canon renderer (AlbumPage) with rank chrome
// suppressed. Visibility = the deep_dives row: a dive is public only when its
// row is status='published' AND the dossier JS is deployed (ESSAYS_FULL[slug]
// exists). Either missing -> bounce to the archive. That row+ESSAYS_FULL pair
// IS the slug validation; there is no separate manifest.
function DeepDiveArticle({ slug, all, user, onAlbum, onHome, onDeepDives }) {
  const { useState, useEffect } = React;
  const [row, setRow] = useState(undefined); // undefined = loading, null = not found, object = found

  useEffect(() => {
    let active = true;
    setRow(undefined);
    if (!window.BBR_supabase) { setRow(null); return; }
    // RLS only returns published rows to anon/authenticated, so this query
    // both fetches the row and enforces the publish gate in one shot.
    window.BBR_supabase
      .from("deep_dives")
      .select("*")
      .eq("slug", slug)
      .eq("status", "published")
      .limit(1)
      .then(({ data }) => { if (active) setRow((data && data[0]) || null); })
      .catch(() => { if (active) setRow(null); });
    return () => { active = false; };
  }, [slug]);

  // Keep the tab title + canonical/social meta meaningful once the row resolves.
  // App's route-meta can't do this for /deep-dive: the dossier carries no
  // title/artist (those live on the row), so we set them here directly.
  useEffect(() => {
    if (!row) return;
    const CFG = window.BBR_DEEPDIVES || {};
    const ddLabel = CFG.LABEL || "Deep Dives";
    const seg = CFG.ARTICLE || "deep-dive";
    const dek = (window.ESSAYS_FULL && window.ESSAYS_FULL[slug] && window.ESSAYS_FULL[slug].essay && window.ESSAYS_FULL[slug].essay.dek) || "";
    const title = row.title + " — " + row.artist + " | " + ddLabel + " | The Lead-In";
    const desc = row.excerpt || dek || (row.title + " by " + row.artist + (row.year ? " (" + row.year + ")" : "") + " — a full Lead-In dossier outside the ranked hundred.");
    const url = "https://www.theleadin.com/" + seg + "/" + encodeURIComponent(slug);
    document.title = title;
    const set = (sel, attr, val) => { const el = document.head.querySelector(sel); if (el) el.setAttribute(attr, val); };
    set('meta[name="description"]', "content", desc);
    set('meta[property="og:title"]', "content", title);
    set('meta[property="og:description"]', "content", desc);
    set('meta[name="twitter:title"]', "content", title);
    set('meta[name="twitter:description"]', "content", desc);
    set('link[rel="canonical"]', "href", url);
    set('meta[property="og:url"]', "content", url);
    // og/twitter image: the dive's own cover (absolute), not the homepage card.
    // The static prerender (gen_seo.py) sets this for crawlers; this covers
    // JS-aware sharers that re-read the head after hydration.
    const cover = "https://www.theleadin.com/covers/" + encodeURIComponent(slug) + ".jpg?v=2";
    set('meta[property="og:image"]', "content", cover);
    set('meta[name="twitter:image"]', "content", cover);
  }, [row, slug]);

  if (row === undefined) {
    return <div className="dd-state" style={{ maxWidth: 640, margin: "16vh auto", textAlign: "center", opacity: 0.7 }}>Loading…</div>;
  }

  const dossier = window.ESSAYS_FULL && window.ESSAYS_FULL[slug];
  if (!row || !dossier) {
    const ddLabel = (window.BBR_DEEPDIVES && window.BBR_DEEPDIVES.LABEL) || "Deep Dives";
    return (
      <div className="dd-state dd-notfound" style={{ maxWidth: 560, margin: "14vh auto", padding: "0 24px", textAlign: "center" }}>
        <h1 style={{ fontFamily: "var(--serif, Georgia)", fontSize: 28, marginBottom: 12 }}>This deep dive isn’t available.</h1>
        <p style={{ lineHeight: 1.6, opacity: 0.8 }}>It may not have been published yet, or the link is wrong. Browse the archive for everything that’s live.</p>
        <button className="cta" style={{ marginTop: 18 }} onClick={onDeepDives}>All {ddLabel}</button>
      </div>
    );
  }

  // Synthesize the album-shaped object the canon renderer expects. rank is null
  // (suppressed via series). genre/country come from the row so nothing renders
  // undefined; coverUrl drives <Sleeve> (falls back to the typographic sleeve).
  const album = {
    slug: row.slug,
    title: row.title,
    artist: row.artist,
    year: row.year,
    genre: row.genre || "",
    country: row.country || "",
    label: "",
    rank: null,
    relatedAlbumSlug: row.related_album_slug || null,
    excerpt: row.excerpt || "",
    coverUrl: row.cover_url || ("/covers/" + row.slug + ".jpg"),
  };

  // onList -> archive so any "back to the list" affordance lands on /deep-dives.
  return (
    <AlbumPage album={album} all={all} onHome={onHome} onList={onDeepDives} onAlbum={onAlbum} />
  );
}

window.DeepDiveArticle = DeepDiveArticle;
