/* global React, ReactDOM, Nav, Footer, Tag, useApi, renderMarkup, stripMarkup */
const { useMemo } = React;

const TAG = {
  Announcement: "violet",
  Newsletter: "ink",
  Opportunity: "magenta",
  Publication: "blue",
  Press: "amber",
  Event: "emerald",
  "Learning Collaborative": "ink",
};

function formatDate(iso) {
  if (!iso) return "";
  const d = new Date(iso + "T12:00:00");
  if (isNaN(d.getTime())) return iso;
  return d.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
}

function paragraphs(text) {
  if (!text) return [];
  return text.split(/\n{2,}/).map(p => p.trim()).filter(Boolean);
}

function hostnameOf(url) {
  try { return new URL(url).hostname.replace(/^www\./, ""); } catch (_) { return null; }
}

function setMeta(name, content) {
  let el = document.head.querySelector(`meta[name="${name}"]`);
  if (!el) {
    el = document.createElement("meta");
    el.setAttribute("name", name);
    document.head.appendChild(el);
  }
  el.setAttribute("content", content);
}

function setMetaProp(prop, content) {
  let el = document.head.querySelector(`meta[property="${prop}"]`);
  if (!el) {
    el = document.createElement("meta");
    el.setAttribute("property", prop);
    document.head.appendChild(el);
  }
  el.setAttribute("content", content);
}

function setCanonical(href) {
  let el = document.head.querySelector('link[rel="canonical"]');
  if (!el) {
    el = document.createElement("link");
    el.setAttribute("rel", "canonical");
    document.head.appendChild(el);
  }
  el.setAttribute("href", href);
}

/* ────────────────────────────────────────────────────────── */

function Header({ n }) {
  // Learning Collaborative posts belong to Programs, so the breadcrumb returns
  // to that list rather than the news index.
  const isLC = n.cat === "Learning Collaborative";
  const backHref = isLC ? "learning-collaborative.html" : "news.html";
  const backLabel = isLC ? "← SODP Learning Collaborative" : "← All news";
  return (
    <section style={{ padding: "56px 0 32px", borderBottom: "1px solid var(--rule)" }}>
      <div className="wrap" style={{ maxWidth: 760 }}>
        <div style={{ marginBottom: 18 }}>
          <a href={backHref} className="link" style={{ fontSize: 12, color: "var(--ink-3)" }}>{backLabel}</a>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", marginBottom: 22 }}>
          <Tag kind={TAG[n.cat] || "violet"}>{n.cat}</Tag>
          <span className="mono" style={{ color: "var(--ink-4)", fontSize: 12 }}>{n.id}</span>
        </div>
        <h1 className="t-display" style={{ fontSize: "clamp(28px, 3.4vw, 44px)", lineHeight: 1.15 }}>{n.title}</h1>
        <div style={{ marginTop: 22, fontFamily: "var(--type-mono)", fontSize: 12, color: "var(--ink-3)", letterSpacing: "0.04em" }}>
          {n.cat === "Event" && n.eventDate
            ? <>
                <span style={{ color: "var(--ink)", fontWeight: 600 }}>Event date: {formatDate(n.eventDate)}</span>
                <span style={{ margin: "0 8px", color: "var(--ink-4)" }}>·</span>
                <span>Posted {formatDate(n.date)}</span>
              </>
            : formatDate(n.date)}
        </div>
      </div>
    </section>
  );
}

/* ────────────────────────────────────────────────────────── */

function extOf(url) {
  const m = /\.([a-z0-9]+)(?:[?#].*)?$/i.exec(url || "");
  return m ? m[1].toUpperCase() : "FILE";
}

/** Downloadable documents attached to the post (e.g. Learning Collaborative
 *  session slides and handouts), rendered as a "Materials" list. */
function Materials({ items }) {
  return (
    <div style={{ marginTop: 36, paddingTop: 28, borderTop: "1px solid var(--rule)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 18 }}>
        <span className="rule-thick" />
        <span className="eyebrow">Materials</span>
      </div>
      <div>
        {items.map((a, i) => (
          <a
            key={i}
            href={a.url}
            target="_blank"
            rel="noreferrer"
            className="news-row"
            style={{
              display: "flex", alignItems: "center", gap: 14,
              padding: "14px 0",
              borderBottom: "1px solid var(--rule)",
              textDecoration: "none", color: "inherit",
            }}
          >
            <span className="mono" style={{
              fontSize: 10, fontWeight: 600, letterSpacing: "0.08em",
              color: "var(--indigo-500)", border: "1px solid var(--rule-2)",
              borderRadius: 3, padding: "4px 8px", minWidth: 42, textAlign: "center",
              flexShrink: 0,
            }}>
              {extOf(a.url)}
            </span>
            <span style={{ flex: 1, fontSize: 15, fontWeight: 500, color: "var(--ink)" }}>
              {a.name || `Document ${i + 1}`}
            </span>
            <span className="news-row-arrow" style={{ color: "var(--indigo-500)", fontSize: 16 }}>↓</span>
          </a>
        ))}
      </div>
    </div>
  );
}

/** Short label for a series entry — the part of the title after the last
 *  colon ("… AI Use: Week Two" → "Week Two"), or the full title if none. */
function seriesLabel(x) {
  const t = (x.title || "").trim();
  const i = t.lastIndexOf(":");
  const tail = i >= 0 ? t.slice(i + 1).trim() : "";
  return tail || t || formatDate(x.date);
}

/** Sidebar for Learning Collaborative sessions: series navigation (found
 *  automatically by category, current session highlighted), uploaded
 *  documents, facilitators, and related reading. */
function LCSidebar({ n, attachments, series, facilitators, reading, hrefOf }) {
  return (
    <aside className="news-detail-aside">
      {series.length > 1 && (
        <div className="aside-card">
          <span className="eyebrow">SODP Learning Collaborative</span>
          {series.map(x => x.id === n.id ? (
            <div key={x.id} className="aside-series-item is-current">
              <div className="aside-series-label">{seriesLabel(x)}</div>
              <div className="aside-series-date">{formatDate(x.date)} · You are here</div>
            </div>
          ) : (
            <a key={x.id} href={hrefOf(x)} className="aside-series-item">
              <div className="aside-series-label">{seriesLabel(x)}</div>
              <div className="aside-series-date">{formatDate(x.date)}</div>
            </a>
          ))}
        </div>
      )}
      {attachments.length > 0 && (
        <div className="aside-card">
          <span className="eyebrow">Session materials</span>
          {attachments.map((a, i) => (
            <a key={i} href={a.url} target="_blank" rel="noreferrer" className="aside-doc">
              <span className="aside-doc-ext">{extOf(a.url)}</span>
              <span className="aside-doc-name">{a.name || `Document ${i + 1}`}</span>
              <span style={{ color: "var(--indigo-500)" }}>↓</span>
            </a>
          ))}
        </div>
      )}
      {facilitators.length > 0 && (
        <div className="aside-card">
          <span className="eyebrow">Facilitators</span>
          {facilitators.map((f, i) => (
            <div key={i} className="aside-fac">
              <div>
                <div className="aside-fac-name">{f.name}</div>
                {(f.title || f.location) && (
                  <div className="aside-fac-meta">
                    {f.title}{f.title && f.location ? " · " : ""}{f.location}
                  </div>
                )}
                {f.email && <a href={`mailto:${f.email}`} className="aside-fac-email">{f.email}</a>}
              </div>
            </div>
          ))}
        </div>
      )}
      {reading.length > 0 && (
        <div className="aside-card">
          <span className="eyebrow">Related reading</span>
          {reading.map((r, i) => (
            <a key={i} href={r.url} target="_blank" rel="noreferrer" className="aside-read">
              <span className="aside-read-label">{r.label || hostnameOf(r.url) || `Link ${i + 1}`}</span>
              <span className="aside-read-arrow">↗</span>
            </a>
          ))}
        </div>
      )}
    </aside>
  );
}

function Body({ n, all }) {
  const paras = paragraphs(n.body);
  const host = n.link ? hostnameOf(n.link) : null;
  const attachments = Array.isArray(n.attachments) ? n.attachments.filter(a => a && a.url) : [];
  const facilitators = Array.isArray(n.facilitators) ? n.facilitators.filter(f => f && f.name) : [];
  const reading = Array.isArray(n.reading) ? n.reading.filter(r => r && r.url) : [];

  // Learning Collaborative sessions get a sidebar: series navigation,
  // materials, facilitators, and related reading.
  const isLC = n.cat === "Learning Collaborative";
  const series = isLC
    ? all.filter(x => x && x.cat === "Learning Collaborative")
        .sort((a, b) => (a.date < b.date ? -1 : 1))
    : [];
  const dupSlugs = (() => {
    const seen = new Set(), dup = new Set();
    all.forEach(x => {
      if (!x || !x.slug) return;
      if (seen.has(x.slug)) dup.add(x.slug);
      seen.add(x.slug);
    });
    return dup;
  })();
  const hrefOf = (x) => `/news-detail?id=${encodeURIComponent(x.slug && !dupSlugs.has(x.slug) ? x.slug : x.id)}`;
  const sidebar = isLC && (attachments.length > 0 || series.length > 1 || facilitators.length > 0 || reading.length > 0);

  const article = (
    <div>
      {n.image && (
        <div style={{ marginBottom: 40, borderRadius: 6, overflow: "hidden", background: "var(--bg-soft)" }}>
          <img
            src={n.image}
            alt={n.title || ""}
            style={{ display: "block", width: "100%", height: "auto" }}
          />
        </div>
      )}

      <div className="webinar-prose">
        {paras.length === 0
          ? <p style={{ color: "var(--ink-3)" }}>{n.link ? "Full details at the external link below." : "Details coming soon."}</p>
          : renderMarkup(n.body)}
      </div>

      {!sidebar && attachments.length > 0 && <Materials items={attachments} />}

      {n.link && (
        <div style={{ marginTop: 36, paddingTop: 28, borderTop: "1px solid var(--rule)" }}>
          <a
            href={n.link}
            target="_blank"
            rel="noreferrer"
            className="btn btn-primary"
          >
            {(n.linkText && n.linkText.trim())
              ? n.linkText.trim()
              : (host ? `Read on ${host}` : "Read full article")} →
          </a>
        </div>
      )}
    </div>
  );

  if (!sidebar) {
    return (
      <section style={{ padding: "48px 0 96px" }}>
        <div className="wrap" style={{ maxWidth: 760 }}>{article}</div>
      </section>
    );
  }

  return (
    <section style={{ padding: "48px 0 96px" }}>
      <div className="wrap" style={{ maxWidth: 1100 }}>
        <div className="news-detail-grid">
          {article}
          <LCSidebar n={n} attachments={attachments} series={series} facilitators={facilitators} reading={reading} hrefOf={hrefOf} />
        </div>
      </div>
    </section>
  );
}

/* ────────────────────────────────────────────────────────── */

function NotFound({ slug }) {
  return (
    <section style={{ padding: "120px 0", textAlign: "center" }}>
      <div className="wrap" style={{ maxWidth: 600 }}>
        <div className="eyebrow" style={{ marginBottom: 16, color: "var(--ink-4)" }}>/ 404</div>
        <h1 className="t-h1" style={{ marginBottom: 16 }}>News item not found.</h1>
        <p className="body" style={{ color: "var(--ink-3)", marginBottom: 28 }}>
          {slug ? <>No news item matches the slug <span className="mono">{slug}</span>.</> : <>No news item selected.</>}
        </p>
        <a href="news.html" className="btn btn-primary">Browse all news</a>
      </div>
    </section>
  );
}

function LoadingState() {
  return (
    <section style={{ padding: "80px 0" }}>
      <div className="wrap" style={{ maxWidth: 760 }}>
        <div style={{ background: "var(--rule)", height: 16, width: 120, borderRadius: 3, marginBottom: 20 }} />
        <div style={{ background: "var(--rule)", height: 44, width: "80%", borderRadius: 3, marginBottom: 14 }} />
        <div style={{ background: "var(--rule)", height: 44, width: "60%", borderRadius: 3, marginBottom: 40 }} />
        <div style={{ background: "var(--rule)", height: 16, width: "100%", borderRadius: 3, marginBottom: 10 }} />
        <div style={{ background: "var(--rule)", height: 16, width: "94%", borderRadius: 3, marginBottom: 10 }} />
        <div style={{ background: "var(--rule)", height: 16, width: "88%", borderRadius: 3 }} />
      </div>
    </section>
  );
}

/* ────────────────────────────────────────────────────────── */

function NewsItemPage() {
  // Resolve slug from /news/<slug> path (if Pages rewrite is wired) or
  // from ?id=<slug> on news-detail.html. The query-string form is the
  // canonical fallback because the Pages rewrite has been flaky.
  const slug = useMemo(() => {
    const m = window.location.pathname.match(/^\/news\/(.+?)\/?$/);
    if (m) return decodeURIComponent(m[1]);
    return new URLSearchParams(window.location.search).get("id");
  }, []);
  const { data, loading } = useApi("news", []);

  const n = useMemo(() => {
    if (!Array.isArray(data)) return null;
    // Match by slug first; fall back to id so list pages can disambiguate
    // legacy items that share a slug by linking with the (unique) id instead.
    return data.find(x => x && x.slug === slug)
      || data.find(x => x && x.id === slug)
      || null;
  }, [data, slug]);

  if (n && document.title.indexOf(n.title) === -1) {
    const canonicalUrl = `https://www.sodpsych.com/news/${encodeURIComponent(n.slug || "")}`;
    const firstPara = stripMarkup((n.body || "").split(/\n{2,}/)[0] || "");
    const description = (firstPara || `A ${n.cat || "news"} update from the Society of Digital Psychiatry.`).slice(0, 280);
    const ogImage = n.image || "https://www.sodpsych.com/images/Logo.png";
    document.title = `${n.title} · Society of Digital Psychiatry`;
    setMeta("description", description);
    setMetaProp("og:title", n.title);
    setMetaProp("og:description", description);
    setMetaProp("og:url", canonicalUrl);
    setMetaProp("og:image", ogImage);
    setMetaProp("og:type", "article");
    setMeta("twitter:title", n.title);
    setMeta("twitter:description", description);
    setMeta("twitter:image", ogImage);
    setCanonical(canonicalUrl);
  }

  return (
    <>
      <Nav active={n && n.cat === "Learning Collaborative" ? "programs" : "news"} />
      {loading && !n ? <LoadingState />
        : !n ? <NotFound slug={slug} />
        : <>
            <Header n={n} />
            <Body n={n} all={Array.isArray(data) ? data : []} />
          </>}
      <Footer />
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<NewsItemPage />);
