// v2-blog.jsx — Blog index + post pages, fetched from the CMS (Payload)

const { useState: useBlogState, useEffect: useBlogEffect } = React;

const BLOG_CMS_API_URL = "https://cms.obsidian-studio.io";

// ── Lexical rich text → React (minimal renderer for Payload's default editor) ──
function lexicalTextNode(node, key) {
  let el = node.text;
  const fmt = node.format || 0;
  if (fmt & 16) el = <code key="code">{el}</code>;
  if (fmt & 1) el = <strong key="b">{el}</strong>;
  if (fmt & 2) el = <em key="i">{el}</em>;
  if (fmt & 8) el = <u key="u">{el}</u>;
  if (fmt & 4) el = <s key="s">{el}</s>;
  return <React.Fragment key={key}>{el}</React.Fragment>;
}

function lexicalChildren(children) {
  return (children || []).map((c, i) => lexicalNode(c, i));
}

function lexicalNode(node, key) {
  if (!node) return null;
  switch (node.type) {
    case "text":
      return lexicalTextNode(node, key);
    case "linebreak":
      return <br key={key} />;
    case "paragraph":
      return <p key={key}>{lexicalChildren(node.children)}</p>;
    case "heading": {
      const Tag = node.tag || "h2";
      return <Tag key={key}>{lexicalChildren(node.children)}</Tag>;
    }
    case "quote":
      return <blockquote key={key}>{lexicalChildren(node.children)}</blockquote>;
    case "list": {
      const Tag = node.tag === "ol" ? "ol" : "ul";
      return <Tag key={key}>{lexicalChildren(node.children)}</Tag>;
    }
    case "listitem":
      return <li key={key}>{lexicalChildren(node.children)}</li>;
    case "link":
      return (
        <a
          key={key}
          href={(node.fields && node.fields.url) || "#"}
          target={node.fields && node.fields.newTab ? "_blank" : undefined}
          rel={node.fields && node.fields.newTab ? "noopener noreferrer" : undefined}
        >
          {lexicalChildren(node.children)}
        </a>
      );
    case "horizontalrule":
      return <hr key={key} />;
    default:
      return node.children ? <React.Fragment key={key}>{lexicalChildren(node.children)}</React.Fragment> : null;
  }
}

function LexicalContent({ content }) {
  if (!content || !content.root) return null;
  return <div className="blog-content">{lexicalChildren(content.root.children)}</div>;
}

// ── BLOG INDEX ─────────────────────────────────────────────────
function BlogIndexPage2({ onOpenPost }) {
  const [posts, setPosts] = useBlogState(null);

  useBlogEffect(() => {
    fetch(`${BLOG_CMS_API_URL}/api/posts?limit=100&sort=-publishedAt`)
      .then((res) => res.json())
      .then((data) => setPosts(data.docs || []))
      .catch((err) => { console.error("Failed to load posts:", err); setPosts([]); });
  }, []);

  return (
    <div className="page2">
      <section className="page-hero" data-screen-label="Blog — hero">
        <Reveal><IndexLine n="01" tone="dark">Blog</IndexLine></Reveal>
        <Reveal delay={120}>
          <h1 className="d1" style={{ color: "var(--w-1)" }}>
            Field notes,<br /><em>from the studio.</em>
          </h1>
        </Reveal>
        <Reveal delay={200}>
          <p className="ed-standfirst">Process, light, and the craft behind the frames — occasional writing from the team.</p>
        </Reveal>
      </section>

      <section className="sec dark tight" data-screen-label="Blog — list">
        {!posts && <p style={{ color: "var(--w-3)" }}>Loading…</p>}
        {posts && posts.length === 0 && (
          <p style={{ color: "var(--w-3)" }}>No posts published yet — check back soon.</p>
        )}
        {posts && posts.length > 0 && (
          <div className="sw-cine">
            {posts.map((post) => (
              <Reveal key={post.slug}>
                <button type="button" className="sw-cine-item work-card" onClick={() => onOpenPost(post.slug)}>
                  {post.cover && post.cover.url ? (
                    <Photo id={post.cover.url} ratio="21/9" alt={post.title} />
                  ) : (
                    <div className="plate" style={{ aspectRatio: "21/9", background: "var(--black-2)" }} />
                  )}
                  <div className="sw-cine-scrim"></div>
                  <div className="sw-cine-cap">
                    <div className="sw-cine-top">
                      {post.publishedAt && (
                        <span className="label" style={{ color: "var(--w-2)" }}>
                          {new Date(post.publishedAt).toLocaleDateString("en-GB", { day: "numeric", month: "long", year: "numeric" })}
                        </span>
                      )}
                      <span className="sw-cine-view label">Read →</span>
                    </div>
                    <span className="sw-cine-title">{post.title}</span>
                    <span className="sw-cine-sub">{post.excerpt}</span>
                  </div>
                </button>
              </Reveal>
            ))}
          </div>
        )}
      </section>
    </div>
  );
}

// ── BLOG POST ──────────────────────────────────────────────────
function BlogPostPage2({ slug, onBack }) {
  const [post, setPost] = useBlogState(undefined); // undefined = loading, null = not found

  useBlogEffect(() => {
    setPost(undefined);
    fetch(`${BLOG_CMS_API_URL}/api/posts?where[slug][equals]=${encodeURIComponent(slug)}&depth=1`)
      .then((res) => res.json())
      .then((data) => setPost((data.docs && data.docs[0]) || null))
      .catch((err) => { console.error("Failed to load post:", err); setPost(null); });
  }, [slug]);

  if (post === undefined) {
    return (
      <div className="page2">
        <section className="page-hero" data-screen-label="Blog post — loading">
          <Reveal><IndexLine n="—" tone="dark">Blog</IndexLine></Reveal>
        </section>
      </div>
    );
  }

  if (post === null) {
    return (
      <div className="page2">
        <section className="page-hero" data-screen-label="Blog post — not found">
          <Reveal><IndexLine n="—" tone="dark">Blog</IndexLine></Reveal>
          <Reveal delay={120}>
            <h1 className="d1" style={{ color: "var(--w-1)" }}>Post not found.</h1>
          </Reveal>
          <Reveal delay={220}>
            <LineLink tone="dark" onClick={onBack}>Back to blog</LineLink>
          </Reveal>
        </section>
      </div>
    );
  }

  return (
    <div className="page2">
      <section className="page-hero" data-screen-label={`Blog — ${post.title}`}>
        <Reveal>
          <div className="cs-crumb label">
            <button type="button" onClick={onBack}>Blog</button>
            <span className="sep">/</span>
            <span className="cur">{post.title}</span>
          </div>
        </Reveal>
        <Reveal delay={120}>
          <h1 className="d1" style={{ color: "var(--w-1)" }}>{post.title}</h1>
        </Reveal>
        {post.publishedAt && (
          <Reveal delay={200}>
            <span className="label" style={{ color: "var(--w-3)" }}>
              {new Date(post.publishedAt).toLocaleDateString("en-GB", { day: "numeric", month: "long", year: "numeric" })}
            </span>
          </Reveal>
        )}
      </section>

      {post.cover && post.cover.url && (
        <section className="sec dark tight slim-b" data-screen-label="Blog post — cover">
          <Reveal><Photo id={post.cover.url} ratio="16/9" alt={post.title} /></Reveal>
        </section>
      )}

      <section className="sec dark" data-screen-label="Blog post — content">
        <Reveal><LexicalContent content={post.content} /></Reveal>
      </section>
    </div>
  );
}

Object.assign(window, { BlogIndexPage2, BlogPostPage2 });
