/* BlogIndex — list of posts with intro, tag filter, year grouping, density-aware rows. */

function BlogIndex({ onOpenPost, query, activeTag, onSetTag, density }) {
  const posts = window.BLOG_POSTS;
  const tags = window.BLOG_TAGS;
  const [vw, setVw] = React.useState(window.innerWidth);
  React.useEffect(() => {
    const update = () => setVw(window.innerWidth);
    window.addEventListener('resize', update, { passive: true });
    return () => window.removeEventListener('resize', update);
  }, []);

  const q = (query || "").trim().toLowerCase();
  const filtered = posts.filter(p => {
    if (activeTag && !p.tags.includes(activeTag)) return false;
    if (!q) return true;
    return (
      p.title.toLowerCase().includes(q) ||
      p.summary.toLowerCase().includes(q) ||
      p.tags.some(t => t.toLowerCase().includes(q))
    );
  });

  const byYear = {};
  for (const p of filtered) (byYear[p.year] = byYear[p.year] || []).push(p);
  const years = Object.keys(byYear).sort((a, b) => b - a);

  const featured = !q && !activeTag ? posts.find(p => p.featured) : null;

  return (
    <main style={biStyles.main}>
      <header style={biStyles.head}>
        <div className="eyebrow" style={biStyles.eyebrow}>Notes from the field</div>
        <h1 style={biStyles.h1}>Writing.</h1>
        <p style={biStyles.lede}>
          Essays and field notes on systems design, engineering practice, and the
          quieter parts of doing technical work. Occasionally the side projects,
          tools, and books that distract me from those.
        </p>
        <div style={biStyles.byline}>
          <span style={biStyles.bylineDot}></span>
          Updated when I have something to say · {posts.length} posts
        </div>
      </header>

      {/* Filter row */}
      <div style={biStyles.filterRow} role="toolbar" aria-label="Filter posts">
        <button type="button"
                onClick={() => onSetTag(null)}
                style={chipStyle(!activeTag)}>
          All
          <span style={biStyles.chipCount}>{posts.length}</span>
        </button>
        {tags.map(t => {
          const count = posts.filter(p => p.tags.includes(t)).length;
          const active = activeTag === t;
          return (
            <button key={t} type="button"
                    onClick={() => onSetTag(active ? null : t)}
                    style={chipStyle(active)}>
              #{t}
              <span style={biStyles.chipCount}>{count}</span>
            </button>
          );
        })}
      </div>

      {/* Featured callout */}
      {featured ? <FeaturedCard post={featured} onOpenPost={onOpenPost} /> : null}

      {/* Empty state */}
      {filtered.length === 0 ? (
        <div style={biStyles.empty}>
          <div style={biStyles.emptyTitle}>Nothing matches.</div>
          <div style={biStyles.emptySub}>
            Try clearing the filter or {" "}
            <button type="button" onClick={() => onSetTag(null)} style={biStyles.emptyLink}>showing everything</button>.
          </div>
        </div>
      ) : null}

      {/* Year groups */}
      {years.map(year => (
        <section key={year} style={biStyles.yearSection}>
          <div style={biStyles.yearLabel}>
            <span>{year}</span>
            <span style={biStyles.yearCount}>{byYear[year].length} post{byYear[year].length === 1 ? "" : "s"}</span>
          </div>
          <ul style={biStyles.list}>
            {byYear[year].map((post, i) => (
              <li key={post.id}
                  style={{ borderBottom: i === byYear[year].length - 1 ? "none" : "1px solid var(--border-subtle)" }}>
                <BlogIndexRow post={post} onClick={() => onOpenPost(post.id)} density={density} isMobile={vw < 640} />
              </li>
            ))}
          </ul>
        </section>
      ))}
    </main>
  );
}

function chipStyle(active) {
  return {
    display: "inline-flex", alignItems: "center", gap: 6,
    height: 26, padding: "0 10px",
    fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.01em",
    color: active ? "var(--accent)" : "var(--fg-secondary)",
    background: active ? "var(--accent-bg)" : "var(--bg-subtle)",
    border: `1px solid ${active ? "transparent" : "var(--border-subtle)"}`,
    borderRadius: 6, cursor: "pointer",
    transition: "background 160ms, color 160ms, border-color 160ms",
  };
}

function FeaturedCard({ post, onOpenPost }) {
  const [hover, setHover] = React.useState(false);
  const canHover = window.matchMedia("(hover: hover)").matches;
  return (
    <a href="#"
       onClick={(e) => { e.preventDefault(); onOpenPost(post.id); }}
       onMouseEnter={canHover ? () => setHover(true) : undefined}
       onMouseLeave={canHover ? () => setHover(false) : undefined}
       style={{
         display: "block", marginBottom: 56,
         padding: "28px 28px 26px",
         background: "var(--surface)",
         border: `1px solid ${hover ? "var(--border-strong)" : "var(--border)"}`,
         borderRadius: 14,
         textDecoration: "none", color: "inherit",
         transition: "border-color 160ms, transform 220ms, box-shadow 220ms",
         boxShadow: hover ? "var(--shadow-md)" : "none",
         transform: hover ? "translateY(-1px)" : "none",
         position: "relative", overflow: "hidden",
       }}>
      {/* subtle accent radial */}
      <span aria-hidden="true" style={{
        position: "absolute", inset: 0, pointerEvents: "none",
        background: "radial-gradient(600px circle at 100% 0%, color-mix(in oklab, var(--accent) 9%, transparent), transparent 60%)",
      }}></span>
      <div style={{ position: "relative" }}>
        <div style={fcStyles.eyebrow}>
          <span style={fcStyles.badge}>Latest</span>
          <span style={fcStyles.meta}>{post.date}</span>
          <span style={{ opacity: 0.4 }}>·</span>
          <span style={fcStyles.meta}>{post.read} read</span>
        </div>
        <h2 style={fcStyles.title}>{post.title}</h2>
        <p style={fcStyles.summary}>{post.summary}</p>
        <div style={fcStyles.tags}>
          {post.tags.map(t => <span key={t} style={fcStyles.tag}>#{t}</span>)}
          <span style={{ flex: 1 }}></span>
          <span style={fcStyles.cta}>
            Read post <i data-lucide="arrow-right" style={{ width: 14, height: 14 }}></i>
          </span>
        </div>
      </div>
    </a>
  );
}

const fcStyles = {
  eyebrow: { display: "flex", alignItems: "center", gap: 10, fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-tertiary)" },
  badge: {
    display: "inline-flex", alignItems: "center", height: 20, padding: "0 8px",
    background: "var(--accent-bg)", color: "var(--accent)",
    borderRadius: 999, fontSize: 10, fontWeight: 600,
    fontFamily: "var(--font-text)", letterSpacing: "0.02em",
    textTransform: "uppercase",
  },
  meta: { letterSpacing: "0.01em" },
  title: {
    margin: "14px 0 10px", fontFamily: "var(--font-display)",
    fontSize: 30, fontWeight: 600, letterSpacing: "-0.018em", lineHeight: 1.1,
    color: "var(--fg)", textWrap: "balance",
  },
  summary: { margin: 0, fontSize: 16, lineHeight: 1.55, color: "var(--fg-secondary)", maxWidth: 640 },
  tags: { display: "flex", alignItems: "center", gap: 10, marginTop: 20, flexWrap: "wrap" },
  tag: { fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-tertiary)" },
  cta: { display: "inline-flex", alignItems: "center", gap: 6, fontSize: 13, fontWeight: 600, color: "var(--accent)" },
};

function BlogIndexRow({ post, onClick, density, isMobile }) {
  const [hover, setHover] = React.useState(false);
  const compact = density === "compact";
  const canHover = window.matchMedia("(hover: hover)").matches;
  return (
    <a href="#"
       onClick={(e) => { e.preventDefault(); onClick(); }}
       onMouseEnter={canHover ? () => setHover(true) : undefined}
       onMouseLeave={canHover ? () => setHover(false) : undefined}
       style={{
         display: "grid",
         gridTemplateColumns: isMobile ? "1fr 24px" : "128px 1fr 28px",
         gap: isMobile ? 12 : 24, alignItems: "flex-start",
         padding: compact ? "16px 16px" : "22px 16px",
         margin: "0 -16px",
         textDecoration: "none", color: "inherit",
         borderRadius: 12,
         background: hover ? "var(--bg-subtle)" : "transparent",
         transition: "background 160ms",
       }}>
      {!isMobile && <div style={birStyles.date}>{post.date}</div>}
      <div>
        {isMobile && <div style={{ ...birStyles.date, marginBottom: 4 }}>{post.date}</div>}
        <div style={birStyles.titleRow}>
          {post.kind === "til" ? <span style={birStyles.kind}>TIL</span> : null}
          {post.kind === "review" ? <span style={birStyles.kindAlt}>Review</span> : null}
          <span style={{ ...birStyles.title, fontSize: compact ? 19 : 22 }}>{post.title}</span>
        </div>
        {!compact ? <div style={birStyles.summary}>{post.summary}</div> : null}
        <div style={birStyles.meta}>
          <span>{post.read} read</span>
          <span style={{ opacity: 0.4 }}>·</span>
          {post.tags.map((t, i) => (
            <React.Fragment key={t}>
              {i > 0 ? <span style={{ opacity: 0.4 }}>·</span> : null}
              <span style={birStyles.tag}>#{t}</span>
            </React.Fragment>
          ))}
        </div>
      </div>
      <div style={{ ...birStyles.chev, transform: hover ? "translateX(2px)" : "none", transition: "transform 220ms" }}>
        <i data-lucide="arrow-right" style={{ width: 16, height: 16 }}></i>
      </div>
    </a>
  );
}

const biStyles = {
  main: { maxWidth: 880, margin: "0 auto", padding: "72px max(20px, 5vw) 96px" },
  head: { marginBottom: 48 },
  eyebrow: { marginBottom: 16 },
  h1: { fontFamily: "var(--font-display)", fontSize: "clamp(36px, 9vw, 72px)", fontWeight: 600, letterSpacing: "-0.024em", lineHeight: 1.02, margin: 0 },
  lede: { marginTop: 22, fontSize: "clamp(15px, 3vw, 19px)", lineHeight: 1.55, color: "var(--fg-secondary)", maxWidth: 620, textWrap: "pretty" },
  byline: {
    marginTop: 24, display: "inline-flex", alignItems: "center", gap: 10,
    fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--fg-tertiary)",
  },
  bylineDot: { width: 6, height: 6, borderRadius: "50%", background: "var(--green-500)", display: "inline-block" },
  bylineLink: { color: "var(--accent)", textDecoration: "none" },

  filterRow: {
    display: "flex", flexWrap: "wrap", gap: 6,
    paddingBottom: 32,
  },
  chipCount: { fontSize: 10, opacity: 0.55 },

  empty: { padding: "48px 16px", textAlign: "center", color: "var(--fg-tertiary)" },
  emptyTitle: { fontFamily: "var(--font-display)", fontSize: 22, color: "var(--fg-secondary)", marginBottom: 6, letterSpacing: "-0.011em" },
  emptySub: { fontSize: 14 },
  emptyLink: {
    background: "none", border: "none", padding: 0, font: "inherit",
    color: "var(--accent)", cursor: "pointer", textDecoration: "underline",
    textUnderlineOffset: 3,
  },

  yearSection: { marginBottom: 48 },
  yearLabel: {
    display: "flex", justifyContent: "space-between", alignItems: "baseline",
    fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--fg-tertiary)",
    letterSpacing: "0.08em", textTransform: "uppercase",
    paddingBottom: 12, borderBottom: "1px solid var(--border)",
    marginBottom: 4,
  },
  yearCount: { letterSpacing: "0.04em", color: "var(--fg-quaternary)", fontSize: 11 },
  list: { listStyle: "none", padding: 0, margin: 0 },
};
const birStyles = {
  date: { fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--fg-tertiary)", paddingTop: 6 },
  titleRow: { display: "flex", alignItems: "baseline", gap: 8, flexWrap: "wrap" },
  title: { fontFamily: "var(--font-display)", fontWeight: 600, letterSpacing: "-0.012em", color: "var(--fg)", lineHeight: 1.2 },
  kind: {
    fontFamily: "var(--font-mono)", fontSize: 9, fontWeight: 600,
    letterSpacing: "0.08em", textTransform: "uppercase",
    color: "var(--amber-500)", background: "var(--amber-100)",
    padding: "2px 6px", borderRadius: 4,
    transform: "translateY(-2px)",
  },
  kindAlt: {
    fontFamily: "var(--font-mono)", fontSize: 9, fontWeight: 600,
    letterSpacing: "0.08em", textTransform: "uppercase",
    color: "var(--green-500)", background: "var(--green-100)",
    padding: "2px 6px", borderRadius: 4,
    transform: "translateY(-2px)",
  },
  summary: { marginTop: 6, fontSize: 15, color: "var(--fg-tertiary)", lineHeight: 1.55, maxWidth: 580, textWrap: "pretty" },
  meta: { marginTop: 12, display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-tertiary)" },
  tag: { color: "var(--fg-secondary)" },
  chev: { color: "var(--fg-quaternary)", display: "flex", justifyContent: "flex-end", paddingTop: 6 },
};

window.BlogIndex = BlogIndex;
