// blog.jsx — BlogList (index) + BlogArticle (single post).
// Reads from Sanity via window.__sanity. Matches the site's dark theme.

const { useEffect, useState, useMemo } = React;

// ---------- helpers ----------
function fmtDate(iso) {
  if (!iso) return "";
  const d = new Date(iso);
  if (isNaN(d)) return "";
  return d.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
}

function readMins(rt) {
  const n = Math.max(1, Math.round(rt || 0));
  return n;
}

function cover(url, opts) {
  if (!url) return null;
  return window.__sanity ? window.__sanity.sized(url, opts) : url;
}

// SPA link — intercepted by the global handler in index.html (data-spa).
function SpaLink({ to, className, children, onClick }) {
  return (
    <a href={to} data-spa="" className={className} onClick={onClick}>
      {children}
    </a>
  );
}

// ---------- shared states ----------
function BlogNotice({ kind, t }) {
  const msg =
    kind === "error" ? (t ? t("blog.error") : "Couldn't load articles.")
    : kind === "empty" ? (t ? t("blog.empty") : "No articles yet.")
    : (t ? t("blog.loading") : "Loading…");
  return (
    <div className={`blog-notice blog-notice--${kind}`}>
      <span className="dot" aria-hidden="true" />
      {msg}
    </div>
  );
}

// ============================================================
//  BLOG LIST
// ============================================================
function BlogList({ t }) {
  const [posts, setPosts] = useState(null);
  const [status, setStatus] = useState("loading"); // loading | ready | empty | error
  const [activeTag, setActiveTag] = useState(null);

  useEffect(() => {
    let alive = true;
    if (!window.__sanity) { setStatus("error"); return; }
    window.__sanity.getPosts()
      .then((data) => {
        if (!alive) return;
        const list = Array.isArray(data) ? data : [];
        setPosts(list);
        setStatus(list.length ? "ready" : "empty");
      })
      .catch(() => { if (alive) setStatus("error"); });
    return () => { alive = false; };
  }, []);

  useEffect(() => {
    document.title = (t ? t("blog.title") : "Blog") + " — Traffy";
  }, [t]);

  // unique tags across all posts, for the filter row
  const tags = useMemo(() => {
    if (!posts) return [];
    const seen = new Map();
    posts.forEach((p) => (p.tags || []).forEach((tag) => {
      if (tag && tag.slug && !seen.has(tag.slug)) seen.set(tag.slug, tag);
    }));
    return Array.from(seen.values());
  }, [posts]);

  const visible = useMemo(() => {
    if (!posts) return [];
    if (!activeTag) return posts;
    return posts.filter((p) => (p.tags || []).some((tag) => tag.slug === activeTag));
  }, [posts, activeTag]);

  return (
    <main className="blog">
      <section className="section blog-index">
        <div className="section-inner">
          <header className="blog-head reveal">
            <nav className="blog-crumbs" aria-label="Breadcrumb">
              <a href="/" data-spa="">{t ? t("blog.home") : "Home page"}</a>
              <span className="blog-crumb-sep" aria-hidden="true">/</span>
              <span className="blog-crumb-current">{t ? t("blog.kicker") : "Blog"}</span>
            </nav>
            <h1 className="blog-title">{t ? t("blog.title") : "Latest news and articles"}</h1>
            <p className="blog-sub">{t ? t("blog.subtitle") : ""}</p>
            {window.__sanity && window.__sanity.isDemo() && (
              <div className="blog-demo-note">{t ? t("blog.demo") : "Demo content — connect Sanity to manage real articles."}</div>
            )}
          </header>

          {status !== "ready" ? (
            <BlogNotice kind={status === "loading" ? "loading" : status} t={t} />
          ) : (
            <>
              {tags.length > 0 && (
                <div className="blog-filters reveal" role="group" aria-label="Filter by tag">
                  <button
                    type="button"
                    className={`blog-chip${activeTag === null ? " is-active" : ""}`}
                    onClick={() => setActiveTag(null)}
                  >
                    {t ? t("blog.filter.all") : "All"}
                  </button>
                  {tags.map((tag) => (
                    <button
                      key={tag.slug}
                      type="button"
                      className={`blog-chip${activeTag === tag.slug ? " is-active" : ""}`}
                      onClick={() => setActiveTag(tag.slug)}
                    >
                      {tag.title}
                    </button>
                  ))}
                </div>
              )}

              <div className="blog-grid">
                {visible.map((p) => (
                  <SpaLink key={p.slug} to={`/blog/${p.slug}`} className="blog-card reveal">
                    <div className="blog-card-cover">
                      {p.cover ? (
                        <img src={cover(p.cover, { w: 720, h: 460, fit: "crop", q: 70 })}
                             alt={p.coverAlt || p.title} loading="lazy" />
                      ) : (
                        <div className="blog-card-cover--empty" aria-hidden="true" />
                      )}
                      {p.tags && p.tags.length > 0 && (
                        <span className="blog-card-tag blog-card-tag--overlay">{p.tags[0].title}</span>
                      )}
                    </div>
                    <div className="blog-card-body">
                      <div className="blog-card-meta">
                        <span>{fmtDate(p.publishedAt)}</span>
                        <span className="blog-card-dot" aria-hidden="true">·</span>
                        <span>{readMins(p.readingTime)} {t ? t("blog.minRead") : "min read"}</span>
                      </div>
                      <h2 className="blog-card-title">{p.title}</h2>
                      {p.excerpt ? <p className="blog-card-excerpt">{p.excerpt}</p> : null}
                      <div className="blog-card-foot">
                        <span className="blog-card-author">{p.author && p.author.name ? p.author.name : ""}</span>
                        <span className="blog-card-read">{t ? t("blog.read") : "Read"} →</span>
                      </div>
                    </div>
                  </SpaLink>
                ))}
              </div>

              {visible.length === 0 && <BlogNotice kind="empty" t={t} />}
            </>
          )}
        </div>
      </section>
    </main>
  );
}

// ============================================================
//  BLOG ARTICLE
// ============================================================
function BlogArticle({ slug, t }) {
  const [post, setPost] = useState(null);
  const [status, setStatus] = useState("loading"); // loading | ready | notfound | error

  useEffect(() => {
    let alive = true;
    window.scrollTo(0, 0);
    if (!window.__sanity) { setStatus("error"); return; }
    setStatus("loading");
    window.__sanity.getPost(slug)
      .then((data) => {
        if (!alive) return;
        if (!data) { setStatus("notfound"); return; }
        setPost(data);
        setStatus("ready");
      })
      .catch(() => { if (alive) setStatus("error"); });
    return () => { alive = false; };
  }, [slug]);

  // SEO meta from Sanity (client-side; see note in summary)
  useEffect(() => {
    if (!post) return;
    const seo = post.seo || {};
    document.title = (seo.metaTitle || post.title) + " — Traffy";
    setMeta("description", seo.metaDescription || post.excerpt || "");
    return () => { document.title = "Traffy — Performance Marketing"; };
  }, [post]);

  if (status !== "ready") {
    return (
      <main className="blog">
        <section className="section blog-article">
          <div className="section-inner article-inner">
            <SpaLink to="/blog" className="article-back">← {t ? t("blog.back") : "All articles"}</SpaLink>
            <BlogNotice kind={status === "loading" ? "loading" : (status === "notfound" ? "empty" : "error")} t={t} />
          </div>
        </section>
      </main>
    );
  }

  const a = post.author || {};
  return (
    <main className="blog">
      <article className="section blog-article">
        <div className="section-inner article-inner">
          <SpaLink to="/blog" className="article-back reveal">← {t ? t("blog.back") : "All articles"}</SpaLink>

          <header className="article-head reveal">
            {post.tags && post.tags.length > 0 && (
              <div className="article-tags">
                {post.tags.map((tag) => (
                  <span key={tag.slug} className="blog-card-tag">{tag.title}</span>
                ))}
              </div>
            )}
            <h1 className="article-title">{post.title}</h1>
            {post.excerpt ? <p className="article-excerpt">{post.excerpt}</p> : null}
            <div className="article-byline">
              {a.avatar ? (
                <img className="article-avatar" src={cover(a.avatar, { w: 80, h: 80, fit: "crop" })} alt={a.name || ""} />
              ) : null}
              <div className="article-byline-text">
                {a.name ? (
                  <span className="article-author">
                    {a.name}{a.role ? <span className="article-role"> · {a.role}</span> : null}
                  </span>
                ) : null}
                <span className="article-meta">
                  {fmtDate(post.publishedAt)}
                  <span className="blog-card-dot" aria-hidden="true"> · </span>
                  {readMins(post.readingTime)} {t ? t("blog.minRead") : "min read"}
                </span>
              </div>
            </div>
          </header>

          {post.cover ? (
            <div className="article-cover reveal">
              <img src={cover(post.cover, { w: 1400, q: 80 })} alt={post.coverAlt || post.title} />
            </div>
          ) : null}

          <div className="article-content reveal">
            <PortableText value={post.body} />
          </div>
        </div>
      </article>
    </main>
  );
}

// set/update a <meta name="..."> tag
function setMeta(name, content) {
  let el = document.head.querySelector(`meta[name="${name}"]`);
  if (!el) {
    el = document.createElement("meta");
    el.setAttribute("name", name);
    document.head.appendChild(el);
  }
  el.setAttribute("content", content);
}

Object.assign(window, { BlogList, BlogArticle });
