/* writing.jsx — long-form notes list */

const { useState: useStateW, useEffect: useEffectW, useMemo: useMemoW } = React;

const POSTS_FALLBACK = [
  { n: "012", date: "26.04.04", title: "On the politics of attention", read: "9 min", tag: "Philosophy" },
  { n: "011", date: "26.03.18", title: "Why ferrimagnets are the right substrate, finally", read: "14 min", tag: "Physics" },
  { n: "010", date: "26.02.27", title: "Notes from a stealth quarter", read: "6 min", tag: "Founding" },
  { n: "009", date: "26.02.10", title: "Mark Lombardi as software", read: "11 min", tag: "Design" },
  { n: "008", date: "26.01.22", title: "Reading: Bachelard, then immediately rereading him", read: "7 min", tag: "Philosophy" },
  { n: "007", date: "25.12.30", title: "What I expect from 2026, with error bars", read: "8 min", tag: "Personal" },
  { n: "006", date: "25.12.04", title: "Magnonics, in plain language", read: "12 min", tag: "Physics" },
  { n: "005", date: "25.11.11", title: "Curating is doing user research", read: "5 min", tag: "Culture" },
  { n: "004", date: "25.10.20", title: "On the form of personal sites", read: "6 min", tag: "Design" },
];

function PostRow({ p, idx }) {
  useLang();
  const [hover, setHover] = useStateW(false);
  return (
    <a
      href="#writing"
      onMouseEnter={() => window.__hasHover && setHover(true)}
      onMouseLeave={() => window.__hasHover && setHover(false)}
      data-cursor="link" data-cursor-label={t("Read")}
      className="row-list"
      style={{
        display: "grid", gridTemplateColumns: "60px 110px 1fr 120px 80px 30px",
        alignItems: "baseline", gap: 24,
        padding: "26px 0", borderTop: "1px solid var(--line-soft)",
        cursor: "none", position: "relative",
        background: hover ? "var(--fg)" : "transparent",
        color: hover ? "var(--bg)" : "var(--fg)",
        margin: hover ? "0 -24px" : 0,
        padding: hover ? "26px 24px" : "26px 0",
        transition: "all 280ms var(--easing-default)",
      }}>
      <span className="micro row-n" style={{ color: hover ? "rgba(255,255,255,0.5)" : "var(--fg-muted)" }}>{p.n}</span>
      <span className="micro row-date" style={{ color: hover ? "rgba(255,255,255,0.5)" : "var(--fg-muted)" }}>{p.date}</span>
      <div className="display-md row-title" style={{ fontSize: "clamp(20px, 2vw, 28px)", fontStyle: hover ? "italic" : "normal", transition: "font-style 200ms" }}>
        {t(p.title)}
      </div>
      <span className="micro row-tag">{t(p.tag)}</span>
      <span className="micro row-read" style={{ color: hover ? "rgba(255,255,255,0.5)" : "var(--fg-muted)" }}>{p.read}</span>
      <span className="row-arrow" style={{ fontFamily: "var(--font-mono)", transform: hover ? "translateX(6px)" : "translateX(0)", transition: "transform 280ms" }}>→</span>
    </a>
  );
}

function Writing() {
  useLang();
  const [progress, setProgress] = useStateW(0);
  const [posts, setPosts] = useStateW(POSTS_FALLBACK);
  const [activeTag, setActiveTag] = useStateW("All");
  const [syncState, setSyncState] = useStateW("idle"); // idle | loaded | failed

  // Reading progress
  useEffectW(() => {
    const onScroll = () => {
      const h = document.documentElement.scrollHeight - window.innerHeight;
      setProgress(h > 0 ? (window.scrollY / h) * 100 : 0);
    };
    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  // Notion-synced posts.json (generated by scripts/sync-notion.mjs)
  useEffectW(() => {
    let cancelled = false;
    fetch("posts.json", { cache: "no-cache" })
      .then(r => r.ok ? r.json() : Promise.reject(r.status))
      .then(data => {
        if (cancelled) return;
        if (Array.isArray(data) && data.length) {
          setPosts(data);
          setSyncState("loaded");
        }
      })
      .catch(() => { if (!cancelled) setSyncState("failed"); });
    return () => { cancelled = true; };
  }, []);

  const tags = useMemoW(() => {
    const seen = new Set(["All"]);
    posts.forEach(p => p.tag && seen.add(p.tag));
    const order = ["All", "Physics", "Philosophy", "Design", "Founding", "Culture", "Personal"];
    const known = order.filter(t => seen.has(t));
    const extra = [...seen].filter(t => !order.includes(t));
    return [...known, ...extra];
  }, [posts]);

  const visiblePosts = useMemoW(
    () => activeTag === "All" ? posts : posts.filter(p => p.tag === activeTag),
    [posts, activeTag]
  );

  return (
    <div className="page" style={{ paddingTop: 140 }}>
      {/* Reading progress */}
      <div style={{
        position: "fixed", top: 88, left: 0, right: 0, height: 1, zIndex: 50,
        background: "var(--line-soft)",
      }}>
        <div style={{ width: `${progress}%`, height: "100%", background: "var(--fg)", transition: "width 100ms" }} />
      </div>

      <div className="page-eyebrow">
        <span className="micro">{t("Index")} 06</span>
        <span style={{ width: 24, height: 1, background: "var(--fg)" }} />
        <span className="micro micro-fg">{t("Writing · Long-form notes")}</span>
      </div>

      <div className="responsive-stack" style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr", gap: 64, marginBottom: 80, alignItems: "end" }}>
        <h1 className="display-xl">
          {t("Drafts that survived a second reading.")}
        </h1>
        <div className="body-lg" style={{ color: "var(--fg-muted)" }}>
          {t("Most of these started in Obsidian. They survive here because they kept holding up. Physics, AI, culture, philosophy — usually all four in the same sentence.")}
        </div>
      </div>

      {/* Posts list — disabled for initial deploy. Flip the `false &&`
          wrapper below to re-enable filters + rows once content lands. */}
      {false && (
      <>
      {/* Filter row */}
      <div style={{ display: "flex", gap: 8, marginBottom: 16, flexWrap: "wrap", alignItems: "center" }}>
        {tags.map((tag) => {
          const active = tag === activeTag;
          const count = tag === "All" ? posts.length : posts.filter(p => p.tag === tag).length;
          return (
            <button
              key={tag}
              type="button"
              onClick={() => setActiveTag(tag)}
              data-cursor="link"
              data-cursor-label={t("Filter")}
              style={{
                padding: "8px 14px", border: "1px solid var(--line)",
                fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.08em",
                textTransform: "uppercase",
                background: active ? "var(--fg)" : "transparent",
                color: active ? "var(--bg)" : "var(--fg)",
                cursor: "none",
                transition: "background 200ms var(--easing-default), color 200ms var(--easing-default)",
              }}>
              {t(tag)} <span style={{ opacity: 0.5, marginLeft: 6 }}>{count}</span>
            </button>
          );
        })}
        <span className="micro" style={{ marginLeft: "auto", color: "var(--fg-muted)" }}>
          {syncState === "loaded" ? t("Notion · synced") : syncState === "failed" ? t("Local fallback") : t("Loading…")}
        </span>
      </div>

      <div style={{ marginBottom: 80 }}>
        {visiblePosts.map((p, i) => <PostRow key={p.n || `${p.title}-${i}`} p={p} idx={i} />)}
        {visiblePosts.length === 0 && (
          <div className="body-sm" style={{ padding: "60px 0", color: "var(--fg-muted)", borderTop: "1px solid var(--line-soft)" }}>
            {t("No posts under this tag yet.")}
          </div>
        )}
        <div style={{ borderTop: "1px solid var(--line-soft)" }} />
      </div>
      </>
      )}

      {/* In-preparation placeholder — replaces the list above. */}
      <div style={{
        borderTop: "1px solid var(--line-soft)",
        borderBottom: "1px solid var(--line-soft)",
        padding: "120px 0",
        marginBottom: 80,
        textAlign: "center",
      }}>
        <div className="micro" style={{ marginBottom: 16, color: "var(--fg-muted)" }}>
          {t("Status")}
        </div>
        <div className="display-md" style={{ marginBottom: 12 }}>
          {t("Currently in preparation.")}
        </div>
        <div className="body-sm" style={{ color: "var(--fg-muted)", maxWidth: 420, margin: "0 auto" }}>
          {t("Drafts are being moved over from Obsidian and reviewed. Posts will appear here as they survive a second reading.")}
        </div>
      </div>

      {/* Tufte-style sidenote sample */}
      <div className="responsive-stack" style={{ display: "grid", gridTemplateColumns: "1fr 240px", gap: 48, padding: "60px 0", borderTop: "1px solid var(--line)" }}>
        <div>
          <div className="micro" style={{ marginBottom: 16 }}>{t("Sample · § 1 of post 011")}</div>
          <div className="display-md" style={{ marginBottom: 24, maxWidth: 720 }}>
            {window.__lang === "kr"
              ? <>{t("\"A ferrimagnet is two opposing magnetizations bound together. At one specific temperature, the angular momentum cancels but the magnetization does not. The wall, untethered, moves at the speed the lattice will allow.\"")}<sup style={{ fontSize: 18, color: "var(--fg-muted)" }}>1</sup></>
              : <>"A ferrimagnet is two opposing magnetizations bound together. At one specific temperature, the angular momentum cancels but the magnetization does not<sup style={{ fontSize: 18, color: "var(--fg-muted)" }}>1</sup>. The wall, untethered, moves at the speed the lattice will allow."</>
            }
          </div>
        </div>
        <aside style={{ borderLeft: "1px solid var(--line-soft)", paddingLeft: 16 }}>
          <div className="micro" style={{ marginBottom: 6 }}>{t("1 · Sidenote")}</div>
          <div className="body-sm" style={{ color: "var(--fg-muted)" }}>
            {window.__lang === "kr"
              ? <>정확히는 T<sub>A</sub> — 각운동량 보상 온도. 자화 보상점과는 다른 개념이다.</>
              : <>Specifically, T<sub>A</sub>: the angular momentum compensation temperature, distinct from the magnetization compensation point.</>
            }
          </div>
        </aside>
      </div>
    </div>
  );
}

Object.assign(window, { Writing });
