// Article.jsx — Insights blog components
// Renders the article chrome (header, byline, share, author, related)
// AROUND a slot of pure rich HTML. Also exports the index-card + grid.
//
// Depends on PageShell.jsx (PageShell, InlineCTA), Chrome.jsx, and the
// global window.INSIGHTS_POSTS / window.INSIGHTS_AUTHORS from insights-data.js.

/* Resolve an author key (or inline object) to a full author record. */
function resolveAuthor(author) {
  const A = window.INSIGHTS_AUTHORS || {};
  if (!author) return A.editorial || { name: "Acerti Editorial", role: "", photo: "assets/favicon.png", bio: "" };
  if (typeof author === "string") return A[author] || A.editorial || { name: author, role: "", photo: "assets/favicon.png", bio: "" };
  return author; // inline object
}

/* Pretty date: "2026-06-04" → "June 4, 2026" */
function fmtDate(iso) {
  if (!iso) return "";
  const d = new Date(iso + "T12:00:00");
  if (isNaN(d)) return iso;
  return d.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
}

/* Avatar — headshot (cover) OR brand logo on a dark circle */
const Avatar = ({ author, size = 44 }) => {
  const a = resolveAuthor(author);
  return (
    <div className={"avatar" + (a.logo ? " avatar-logo" : "")} style={{ width: size, height: size }}>
      <img src={a.photo} alt={a.name} />
    </div>
  );
};

/* Meta row used on cards + byline */
const InsMeta = ({ category, date, readTime, light }) => (
  <div className="ins-meta">
    {category && <span className="ins-cat">{category}</span>}
    {category && (date || readTime) && <span className="ins-dot" />}
    {date && <span className="when">{fmtDate(date)}</span>}
    {date && readTime && <span className="ins-dot" />}
    {readTime && <span className="when">{readTime}</span>}
  </div>
);

/* ── Index: a single article card ───────────────────────────── */
const InsightCard = ({ post }) => {
  const href = post.slug.replace(/^insights\//, "").replace(/\.html$/, "");
  const url = "insights/" + href;
  return (
    <a className="ins-card reveal" href={url} data-category={post.category}>
      <div className={"cover" + (post.cover ? "" : " ins-cover-type")}>
        {post.cover
          ? <img src={post.cover} alt="" loading="lazy" />
          : <span className="glyph">{(post.category || "A")[0]}</span>}
        <InsMeta category={post.category} />
      </div>
      <div className="body">
        <h3>{post.title}</h3>
        <p className="excerpt">{post.excerpt}</p>
        <InsMeta date={post.date} readTime={post.readTime} />
      </div>
    </a>
  );
};

/* ── Index: featured (latest) wide card ─────────────────────── */
const FeaturedInsight = ({ post }) => {
  const url = "insights/" + post.slug.replace(/^insights\//, "");
  const slotId = "cover-" + post.slug.replace(/[^a-z0-9]+/gi, "-").replace(/^-|-$/g, "");
  return (
    <div className="ins-featured reveal">
      <div className={"cover" + (post.cover ? " has-photo" : " cover-slot")}>
        {post.cover
          ? <a href={url} aria-label={post.title}><img src={post.cover} alt="" /></a>
          : <image-slot id={slotId} shape="rect" placeholder="Drop a cover photo"></image-slot>}
        {post.cover && <div className="ins-meta-abs"><InsMeta category={post.category} /></div>}
      </div>
      <a className="copy" href={url}>
        <div className="ins-cat" style={{ color: "var(--primary-active)" }}>Latest</div>
        <h2>{post.title}</h2>
        <p>{post.excerpt}</p>
        <div className="ins-meta" style={{ marginTop: 16 }}>
          <span className="when">{fmtDate(post.date)}</span>
          <span className="ins-dot" />
          <span className="when">{post.readTime}</span>
        </div>
      </a>
    </div>
  );
};

/* ── Index page body ────────────────────────────────────────── */
const PAGE_SIZE = 9;   // cards shown before "Load more"

const InsightsIndex = () => {
  const posts = (window.INSIGHTS_POSTS || []).slice();
  const [filter, setFilter] = React.useState("All");
  const [query, setQuery] = React.useState("");
  const [visible, setVisible] = React.useState(PAGE_SIZE);

  // Category chips, each with a count
  const counts = posts.reduce((m, p) => { if (p.category) m[p.category] = (m[p.category] || 0) + 1; return m; }, {});
  const categories = ["All", ...Object.keys(counts).sort((a, b) => counts[b] - counts[a])];

  const q = query.trim().toLowerCase();
  const isBrowsing = q === "" && filter === "All";

  // Full filtered set (newest-first, manifest order preserved)
  const matches = posts.filter((p) => {
    const okCat = filter === "All" || p.category === filter;
    const okQ = q === "" ||
      [p.title, p.excerpt, p.category].filter(Boolean).join(" ").toLowerCase().includes(q);
    return okCat && okQ;
  });

  // While browsing, the newest is the big featured card; otherwise everything is a grid card
  const featured = isBrowsing ? matches[0] : null;
  const listAll = featured ? matches.slice(1) : matches;
  const list = listAll.slice(0, visible);

  // Reset paging whenever the query/filter changes
  React.useEffect(() => { setVisible(PAGE_SIZE); }, [filter, query]);

  const setCat = (c) => setFilter(c);

  return (
    <PageShell active="Insights">
      <PageHero
        chip="Insights"
        breadcrumb={[{ label: "Home", href: "index.html" }, { label: "Insights" }]}
        title="Insights"
        lede="Field notes on nearshore delivery, ERP, and AI-enabled engineering — written by the team building distributed teams for North American companies."
        ctaLabel="Work with us"
        secondaryLabel="Why nearshoring →"
        secondaryHref="why-nearshoring.html"
      />

      <section className="container" style={{ paddingBottom: 96 }}>
        {/* Toolbar: search + categories */}
        {posts.length > 0 && (
          <div className="ins-toolbar">
            <div className="ins-search">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" /></svg>
              <input
                type="search"
                placeholder="Search insights…"
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                aria-label="Search insights"
              />
              {query && <button className="ins-search-clear" onClick={() => setQuery("")} aria-label="Clear search">×</button>}
            </div>
            {categories.length > 2 && (
              <div className="ins-filter">
                {categories.map((c) => (
                  <button
                    key={c}
                    className={"ins-chip" + (filter === c ? " active" : "")}
                    onClick={() => setCat(c)}
                  >{c}{c !== "All" && <span className="ins-chip-n">{counts[c]}</span>}</button>
                ))}
              </div>
            )}
          </div>
        )}

        {posts.length === 0 && (
          <div className="ins-empty">No articles published yet. Check back soon.</div>
        )}

        {/* Result count when filtering/searching */}
        {posts.length > 0 && !isBrowsing && (
          <div className="ins-resultline">
            {matches.length === 0
              ? <>No articles match <strong>“{query || filter}”</strong>.</>
              : <>{matches.length} article{matches.length === 1 ? "" : "s"}{filter !== "All" ? <> in <strong>{filter}</strong></> : null}{q ? <> matching <strong>“{query}”</strong></> : null}.</>}
          </div>
        )}

        {featured && <FeaturedInsight post={featured} />}

        {list.length > 0 && (
          <div className="ins-grid">
            {list.map((p) => <InsightCard key={p.slug} post={p} />)}
          </div>
        )}

        {listAll.length > visible && (
          <div className="ins-more">
            <button className="btn btn-secondary" onClick={() => setVisible((v) => v + PAGE_SIZE)}>
              Load more articles
            </button>
            <span className="ins-more-count">Showing {list.length + (featured ? 1 : 0)} of {matches.length}</span>
          </div>
        )}
      </section>
    </PageShell>
  );
};

/* ── Share bar ──────────────────────────────────────────────── */
const ShareBar = ({ title }) => {
  const [copied, setCopied] = React.useState(false);
  const url = typeof window !== "undefined" ? window.location.href : "";
  const enc = encodeURIComponent;
  const links = {
    linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${enc(url)}`,
    facebook: `https://www.facebook.com/sharer/sharer.php?u=${enc(url)}`,
    x: `https://twitter.com/intent/tweet?text=${enc(title || "")}&url=${enc(url)}`,
  };
  const copy = () => {
    navigator.clipboard && navigator.clipboard.writeText(url).then(() => {
      setCopied(true); setTimeout(() => setCopied(false), 1800);
    });
  };
  return (
    <div className="ins-share">
      <span className="lbl">Share</span>
      <div className="ins-share-btns">
        <a className="ins-sbtn" href={links.linkedin} target="_blank" rel="noopener noreferrer" aria-label="Share on LinkedIn">
          <svg width="17" height="17" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M4.98 3.5C4.98 4.88 3.87 6 2.5 6S0 4.88 0 3.5 1.12 1 2.5 1s2.48 1.12 2.48 2.5zM.22 8h4.56v14H.22V8zm7.5 0h4.37v1.92h.06c.61-1.15 2.1-2.36 4.32-2.36 4.62 0 5.47 3.04 5.47 7v7.44h-4.56v-6.6c0-1.57-.03-3.6-2.19-3.6-2.2 0-2.54 1.72-2.54 3.49V22h-4.56V8z" /></svg>
        </a>
        <a className="ins-sbtn" href={links.x} target="_blank" rel="noopener noreferrer" aria-label="Share on X">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" /></svg>
        </a>
        <a className="ins-sbtn" href={links.facebook} target="_blank" rel="noopener noreferrer" aria-label="Share on Facebook">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M22 12.06C22 6.5 17.52 2 12 2S2 6.5 2 12.06C2 17.08 5.66 21.24 10.44 22v-7.03H7.9v-2.9h2.54V9.85c0-2.52 1.49-3.91 3.78-3.91 1.1 0 2.24.2 2.24.2v2.47h-1.26c-1.24 0-1.63.78-1.63 1.57v1.88h2.77l-.44 2.9h-2.33V22C18.34 21.24 22 17.08 22 12.06z" /></svg>
        </a>
        <button className={"ins-sbtn" + (copied ? " copied" : "")} onClick={copy} aria-label="Copy link">
          {copied
            ? <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg>
            : <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" /></svg>}
        </button>
      </div>
    </div>
  );
};

/* ── Author card ────────────────────────────────────────────── */
const AuthorCard = ({ author }) => {
  const a = resolveAuthor(author);
  if (!a.bio) return null;
  return (
    <div className="ins-author reveal">
      <Avatar author={author} size={56} />
      <div>
        <div className="nm">{a.name}</div>
        <div className="role">{a.role}</div>
        <div className="bio">{a.bio}</div>
      </div>
    </div>
  );
};

/* ── Related insights (auto-picks recent others) ────────────── */
const RelatedInsights = ({ currentSlug }) => {
  const posts = (window.INSIGHTS_POSTS || []).filter((p) => p.slug !== currentSlug).slice(0, 3);
  if (posts.length === 0) return null;
  return (
    <section className="container section ins-related" style={{ paddingTop: 64 }}>
      <div className="section-header reveal" style={{ marginBottom: 28 }}>
        <div className="eyebrow"><span className="mark" />KEEP READING</div>
        <h3 className="display-md">More from Insights.</h3>
      </div>
      <div className="ins-grid">
        {posts.map((p) => <InsightCard key={p.slug} post={p} />)}
      </div>
    </section>
  );
};

/* ── Full article page ──────────────────────────────────────── */
// meta: { slug, category, title, dek, date, readTime, author, cover, coverCaption }
// children: the rich-HTML article body
const ArticlePage = ({ meta, children }) => {
  const a = resolveAuthor(meta.author);
  return (
    <PageShell active="Insights">
      <article className="ins-article">
        <div className="container">
          <header className="ins-head">
            <div className="breadcrumb">
              <a href="index.html">Home</a><span className="sep">/</span>
              <a href="insights.html">Insights</a><span className="sep">/</span>
              <span>{meta.category}</span>
            </div>
            <InsMeta category={meta.category} date={meta.date} readTime={meta.readTime} />
            <h1>{meta.title}</h1>
            {meta.dek && <p className="ins-dek">{meta.dek}</p>}
            <div className="ins-byline">
              <Avatar author={meta.author} size={44} />
              <div className="who">
                <span className="nm">{a.name}</span>
                <span className="sub">{a.role}</span>
              </div>
            </div>
          </header>
        </div>

        {meta.cover && (
          <figure className="ins-cover-fig reveal">
            <img src={meta.cover} alt="" />
            {meta.coverCaption && <figcaption>{meta.coverCaption}</figcaption>}
          </figure>
        )}

        <div className="container">
          <div className="ins-prose">{children}</div>
          <ShareBar title={meta.title} />
          <AuthorCard author={meta.author} />
        </div>

        <RelatedInsights currentSlug={meta.slug} />

        <InlineCTA
          title="Have a project waiting on the right team?"
          body="Get a senior LATAM team scoped, interviewed, and shipping in under two weeks. No retainers, no minimums."
          label="Start a conversation"
        />
      </article>
    </PageShell>
  );
};

Object.assign(window, {
  Avatar, InsMeta, InsightCard, FeaturedInsight, InsightsIndex,
  ShareBar, AuthorCard, RelatedInsights, ArticlePage,
  resolveAuthor, fmtInsightDate: fmtDate,
});
