/* global React, Reveal, SectionHead, CTABlock, FrameworkExplorer */
const { useState: useStateInsights } = React;

const ARTICLES = [
  {
    n: '01',
    cat: 'Governance & Requirements',
    catKey: 'governance',
    title: 'Why requirements fail before anyone writes them',
    teaser: 'The upstream conditions that make good requirements impossible — and what to do about them before the project even begins.',
    date: 'Mar 2025', read: '9 min',
  },
  {
    n: '02',
    cat: 'Complexity & Systems',
    catKey: 'complexity',
    title: 'Complicated, or complex? Why the distinction matters',
    teaser: 'Most organisations apply complicated-problem thinking to complex situations. Here is what changes when you don\u2019t.',
    date: 'Feb 2025', read: '7 min',
  },
  {
    n: '03',
    cat: 'Human Dynamics',
    catKey: 'human',
    title: 'The stakeholder who isn\u2019t in the room',
    teaser: 'On the invisible stakeholders — political, structural, psychological — that determine whether a programme actually lands.',
    date: 'Jan 2025', read: '6 min',
  },
  {
    n: '04',
    cat: 'Business Analysis',
    catKey: 'analysis',
    title: 'Process mapping isn\u2019t the point',
    teaser: 'Why process documentation so often fails — and what fit-for-purpose documentation actually requires.',
    date: 'Dec 2024', read: '8 min',
  },
  {
    n: '05',
    cat: 'Human Dynamics',
    catKey: 'human',
    title: 'What psychological safety actually looks like in practice',
    teaser: 'Beyond the theory: the specific behavioural patterns that create — or destroy — safety in teams under pressure.',
    date: 'Nov 2024', read: '11 min',
  },
  {
    n: '06',
    cat: 'Discernment & Meaning',
    catKey: 'meaning',
    title: 'On vague language in serious meetings',
    teaser: 'Why ambiguity gets rewarded in enterprise environments, and the cost of letting it accumulate unchecked.',
    date: 'Oct 2024', read: '5 min',
  },
  {
    n: '07',
    cat: 'Complexity & Systems',
    catKey: 'complexity',
    title: 'Maps are not territories — but the wrong map still costs you',
    teaser: 'A working note on when to model, when to refuse to model, and the failure mode that lies between the two.',
    date: 'Sep 2024', read: '7 min',
  },
  {
    n: '08',
    cat: 'Business Analysis',
    catKey: 'analysis',
    title: 'Discovery is a discipline, not a phase',
    teaser: 'Most transformation programmes treat discovery as something you finish. The good ones treat it as something you carry.',
    date: 'Aug 2024', read: '8 min',
  },
  {
    n: '09',
    cat: 'Governance & Requirements',
    catKey: 'governance',
    title: 'The thirty questions a good requirement should answer',
    teaser: 'A working checklist for assessing whether a requirement is actually fit for purpose — before it shapes the design.',
    date: 'Jul 2024', read: '12 min',
  },
];

const STRANDS = [
  { key: 'complexity', n: '01', title: 'Complexity & Systems',     body: 'How organisations actually work — as living systems, not machines.' },
  { key: 'analysis',   n: '02', title: 'Business Analysis',        body: 'The craft of requirements, process design, and honest discovery.' },
  { key: 'human',      n: '03', title: 'Human Dynamics',           body: 'Power, psychology, and the invisible forces shaping decisions.' },
  { key: 'governance', n: '04', title: 'Governance & Requirements', body: 'Why rigour at the front of a project is the most undervalued investment.' },
  { key: 'meaning',    n: '05', title: 'Discernment & Meaning',    body: 'The discipline of clear thinking. Why precision in language matters.' },
];

function InsightsPage({ go }) {
  const [activeStrand, setActiveStrand] = useStateInsights(null);

  const toggleStrand = (key) => {
    setActiveStrand((cur) => (cur === key ? null : key));
  };

  const closeStrand = (event) => {
    if (event.key !== 'Escape' || !activeStrand) return;
    event.preventDefault();
    const trigger = document.getElementById(`strand-trigger-${activeStrand}`);
    setActiveStrand(null);
    requestAnimationFrame(() => trigger?.focus({ preventScroll: true }));
  };

  const activeMeta = STRANDS.find((s) => s.key === activeStrand);
  const activeArticles = activeStrand
    ? ARTICLES.filter((a) => a.catKey === activeStrand)
    : [];

  return (
    <div className="page-enter" data-screen-label="Insights">

      {/* HEADER */}
      <section className="page-header">
        <div className="container">
          <span className="label page-locator">Insights · Working notes</span>
          <div className="page-header-grid">
            <h1 className="display-1">
              Ideas, observations,<br />
              <em>working models.</em>
            </h1>
            <p className="page-header-lede lede">
              This is where we put ideas that are too developed for a LinkedIn post and too provisional to call finished frameworks. Articles, observations, working models, and honest analysis of what we see in complex organisations.
            </p>
          </div>
        </div>
      </section>

      {/* ═══ FIVE STRANDS — interactive explorer ═══ */}
      <Reveal as="section" className="section strand-explorer">
        <div className="container">
          <div className="strand-head">
            <h2 className="label section-eyebrow">The five strands</h2>
            <span className="strand-hint-top">
              <span className="strand-hint-rule" aria-hidden="true"></span>
              <span className="label">Select a strand to reveal its writing ↓</span>
            </span>
          </div>

          <div
            className={`strand-stage ${activeStrand ? 'has-active' : ''}`}
            onKeyDown={closeStrand}
          >
            <div className="cat-grid">
              {STRANDS.map((s) => {
                const count = ARTICLES.filter((a) => a.catKey === s.key).length;
                const isActive = activeStrand === s.key;
                return (
                  <button
                    key={s.key}
                    id={`strand-trigger-${s.key}`}
                    type="button"
                    className={`cat-tile ${isActive ? 'is-active' : ''}`}
                    onClick={() => toggleStrand(s.key)}
                    aria-expanded={isActive}
                    aria-controls="strand-panel"
                  >
                    <div className="cat-tile-head">
                      <span className="cat-tile-num">{s.n}</span>
                    </div>
                    <h3 className="cat-tile-title">{s.title}</h3>
                    <p className="cat-tile-body">{s.body}</p>
                    <span className="cat-tile-foot" aria-hidden="true">
                      <span className="cat-tile-count">{String(count).padStart(2, '0')} {count === 1 ? 'piece' : 'pieces'}</span>
                      <span className="cat-tile-arrow">read ↓</span>
                    </span>
                  </button>
                );
              })}
            </div>

            <div
              id="strand-panel"
              className={`strand-reveal ${activeStrand ? 'is-open' : ''}`}
              role="region"
              aria-labelledby={activeStrand ? `strand-trigger-${activeStrand}` : undefined}
              aria-live="polite"
              hidden={!activeStrand}
            >
              <div className="strand-reveal-inner">
                {activeMeta && (
                  <div className="strand-reveal-content">
                    <div className="strand-reveal-meta">
                      <span className="strand-reveal-marker" aria-hidden="true">
                        <span className="srm-num">{activeMeta.n}</span>
                        <span className="srm-rule"></span>
                      </span>
                      <span className="label">
                        {activeArticles.length} {activeArticles.length === 1 ? 'piece written' : 'pieces written'}
                      </span>
                    </div>
                    <div className="strand-reveal-list">
                      {activeArticles.length === 0 && (
                        <div className="strand-reveal-empty">
                          Nothing in this strand yet — more is being written.
                        </div>
                      )}
                      {activeArticles.map((a) => (
                        <article
                          key={a.n}
                          className="strand-article"
                        >
                          <span className="sa-num">{a.n}</span>
                          <span className="sa-body">
                            <span className="sa-title">{a.title}</span>
                            <span className="sa-teaser">{a.teaser}</span>
                          </span>
                          <span className="sa-meta">
                            <span className="sa-date">{a.date}</span>
                            <span className="sa-read">{a.read} read</span>
                          </span>
                        </article>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
      </Reveal>

      <FrameworkExplorer go={go} />

      <CTABlock go={go} />
    </div>
  );
}

window.InsightsPage = InsightsPage;
