const { useState, useEffect, useMemo, useRef } = React;

const MONTHS = [
  "January","February","March","April","May","June",
  "July","August","September","October","November","December",
];

function fmtDate(dateStr) {
  const d = new Date(dateStr + "T00:00:00");
  return {
    month: MONTHS[d.getMonth()],
    monthShort: MONTHS[d.getMonth()].slice(0, 3),
    year: d.getFullYear(),
    iso: dateStr,
  };
}

function issueNum(articles, a) {
  const sorted = [...articles].sort((x, y) => x.meta.date.localeCompare(y.meta.date));
  const idx = sorted.findIndex((x) => x.path === a.path);
  return String(idx + 1).padStart(2, "0");
}

function Masthead({ count }) {
  return (
    <header className="masthead">
      <div className="kicker mono">Project Anteambulo · Monthly letter</div>
      <h1>Letters</h1>
      <p className="lede">
        Monthly letters on building, clarity, finance, technology, AI,
        leadership, ESG, and the practical systems behind better decisions.
      </p>
      <div className="meta-row">
        <span><b>{count}</b>&nbsp; Letters</span>
        <span>Published <b>monthly</b></span>
        <span>By <b>Anteambulo</b></span>
      </div>
    </header>
  );
}

function SearchBar({ q, setQ, count }) {
  return (
    <div className="search-wrap">
      <span className="search-icon">Find&nbsp;/</span>
      <input
        type="search"
        placeholder="search titles, text, tags…"
        value={q}
        onChange={(e) => setQ(e.target.value)}
        aria-label="Search articles"
      />
      <span className="count">{count} {count === 1 ? "result" : "results"}</span>
    </div>
  );
}

function TagFilter({ tags, active, setActive }) {
  return (
    <div className="tags-row">
      <button
        className={`tag-chip ${active === null ? "active" : ""}`}
        onClick={() => setActive(null)}
      >All</button>
      {tags.map((t) => (
        <button
          key={t}
          className={`tag-chip ${active === t ? "active" : ""}`}
          onClick={() => setActive(active === t ? null : t)}
        >{t}</button>
      ))}
    </div>
  );
}

function FeaturedCard({ article, articles, onOpen }) {
  const d = fmtDate(article.meta.date);
  const n = issueNum(articles, article);
  return (
    <article className="featured" onClick={() => onOpen(article.path)}>
      <div className="issue-row">
        <div className="left">
          <span className="mono">Issue № {n}</span>
          <span className="mono">{d.month} {d.year}</span>
          <span className="mono latest-badge">Latest</span>
        </div>
        <span className="mono">{article.meta.readTime}</span>
      </div>
      <h2>{article.meta.title}</h2>
      <p className="dek">{article.meta.dek}</p>
      <span className="read-btn">Read letter</span>
    </article>
  );
}

function ListCard({ article, articles, onOpen }) {
  const d = fmtDate(article.meta.date);
  const n = issueNum(articles, article);
  const tags = Array.isArray(article.meta.tags) ? article.meta.tags : [];
  return (
    <article className="card" onClick={() => onOpen(article.path)}>
      <div className="card-date">
        <span className="month">{d.month}</span>
        <span className="year">{d.year}</span>
        <span className="issue">№ {n}</span>
      </div>
      <div className="card-body">
        <h2>{article.meta.title}</h2>
        <p className="dek">{article.meta.dek}</p>
        <div className="card-tags">
          {tags.map((t) => <span key={t}>— {t}</span>)}
        </div>
      </div>
      <span className="card-arrow">→</span>
    </article>
  );
}

function ArticleList({ articles, variant, onOpen }) {
  if (articles.length === 0) {
    return <div className="empty">No letters match — try a different search.</div>;
  }

  if (variant === "grid") {
    return (
      <div className="article-list grid">
        {articles.map((a) => (
          <ListCard key={a.path} article={a} articles={articles} onOpen={onOpen} />
        ))}
      </div>
    );
  }

  const [first, ...rest] = articles;
  const groups = {};
  rest.forEach((a) => {
    const y = fmtDate(a.meta.date).year;
    (groups[y] = groups[y] || []).push(a);
  });
  const years = Object.keys(groups).sort((a, b) => Number(b) - Number(a));

  return (
    <div className="article-list">
      {variant === "featured" && first && (
        <FeaturedCard article={first} articles={articles} onOpen={onOpen} />
      )}
      {variant === "list" && first && (
        <ListCard article={first} articles={articles} onOpen={onOpen} />
      )}
      {years.map((y) => (
        <React.Fragment key={y}>
          <div className="year-marker">
            <span>Archive · {y}</span>
            <span className="rule" />
          </div>
          {groups[y].map((a) => (
            <ListCard key={a.path} article={a} articles={articles} onOpen={onOpen} />
          ))}
        </React.Fragment>
      ))}
    </div>
  );
}

function Landing({ articles, onOpen, variant }) {
  const [q, setQ] = useState("");
  const [activeTag, setActiveTag] = useState(null);

  const allTags = useMemo(() => {
    const s = new Set();
    articles.forEach((a) => (a.meta.tags || []).forEach((t) => s.add(t)));
    return [...s].sort();
  }, [articles]);

  const filtered = useMemo(() => {
    const needle = q.trim().toLowerCase();
    return articles.filter((a) => {
      if (activeTag && !(a.meta.tags || []).includes(activeTag)) return false;
      if (!needle) return true;
      const hay = [
        a.meta.title,
        a.meta.dek,
        a.meta.excerpt,
        (a.meta.tags || []).join(" "),
        a._plain,
      ].join(" ").toLowerCase();
      return hay.includes(needle);
    });
  }, [articles, q, activeTag]);

  return (
    <main className="landing">
      <Masthead count={articles.length} />
      <div className="controls">
        <SearchBar q={q} setQ={setQ} count={filtered.length} />
        <TagFilter tags={allTags} active={activeTag} setActive={setActiveTag} />
      </div>
      <ArticleList articles={filtered} variant={variant} onOpen={onOpen} />
    </main>
  );
}

Object.assign(window, { Landing, fmtDate, issueNum });
