/* CitationBadge.jsx + ExplainPanel — academic-anchor citation primitive
   Inline badge: [Ref: Centeno 1985]. Click opens a slide-out drawer from the
   right with full citation, venue, DOI/URL, and context. Brutalist register:
   serif title, mono brackets on the badge, no animation flourish, no
   gradient fills. Designed for a Yale-trained reader who reads the badge,
   clicks once, scans the panel, closes it.

   Per Verification Ledger 2026-05-05 (Delta), Section III.
*/

const CITATIONS = {
  /* ───── Inverse Design mathematical lineage ───── */
  'centeno-1985': {
    label: 'Centeno 1985',
    author: 'Centeno, M. L.',
    title: 'On Combining Quota-Share and Excess of Loss',
    venue: 'ASTIN Bulletin: The Journal of the IAA, 15(1), 49-63.',
    year: 1985,
    doi: '10.2143/AST.15.1.2015034',
    url: 'https://doi.org/10.2143/AST.15.1.2015034',
    open_access: 'https://www.casact.org/sites/default/files/database/astin_vol15no1_49.pdf',
    significance: 'Foundational paper of the optimal-reinsurance-design problem. Establishes the formal optimisation of mixing proportional (quota-share) and non-proportional (excess-of-loss) cession under variance and expected-value constraints. The 6-simplex projected gradient descent in this document is a direct computational descendant.',
  },
  'liang-yuen-2010': {
    label: 'Liang & Yuen 2010',
    author: 'Liang, Z., Yuen, K. C.',
    title: 'Optimal combining quota-share and excess of loss reinsurance to maximize the expected utility',
    venue: 'Journal of Applied Mathematics and Computing, 32, 213-235.',
    year: 2010,
    doi: '10.1007/s12190-010-0385-8',
    url: 'https://doi.org/10.1007/s12190-010-0385-8',
    significance: 'Peer-reviewed mathematical anchor for the inverse-design framing. Derives closed-form expressions using stochastic control and Hamilton-Jacobi-Bellman equations for both diffusion and jump-diffusion risk models. Generalises single-class quota-share to the multi-class portfolio problem solved by the engine here.',
  },
  'arxiv-2504-16530': {
    label: 'arXiv:2504.16530',
    author: 'Various',
    title: 'Modern Computational Methods in Reinsurance Optimization: From Simulated Annealing to Quantum Branch & Bound',
    venue: 'arXiv preprint (April 2025).',
    year: 2025,
    url: 'https://arxiv.org/abs/2504.16530',
    significance: 'Contemporary survey of computational reinsurance optimisation, covering attachment points, limits, reinstatement clauses, regulatory constraints. The projected-gradient-on-simplex approach in this document sits squarely in this lineage.',
  },
  'arxiv-2501-06404': {
    label: 'arXiv:2501.06404',
    author: 'Various',
    title: 'A Hybrid Framework for Reinsurance Optimization: Integrating Generative Models and Reinforcement Learning',
    venue: 'arXiv preprint (January 2025).',
    year: 2025,
    url: 'https://arxiv.org/abs/2501.06404',
    significance: 'Variational autoencoders plus reinforcement learning (PPO) for dynamic reinsurance optimisation. Validates the venture\'s positioning at the frontier of computational reinsurance design.',
  },

  /* ───── NZ regulatory anchors ───── */
  'xrb-nzcs': {
    label: 'XRB NZ CS',
    author: 'External Reporting Board (NZ)',
    title: 'Aotearoa New Zealand Climate Standards: NZ CS 1 / NZ CS 2 / NZ CS 3',
    venue: 'External Reporting Board, New Zealand. First effective for accounting periods beginning on or after 1 January 2023.',
    year: 2023,
    url: 'https://www.xrb.govt.nz/standards/climate-related-disclosures/aotearoa-new-zealand-climate-standards/',
    significance: 'Mandatory climate-related disclosure for ~200 NZ Climate Reporting Entities (large public-listed and large financial-sector entities per FMA scope). NZ CS 1 (climate-related risks/opportunities framework), NZ CS 2 (adoption provisions), NZ CS 3 (principles and general requirements).',
  },
  'rbnz-ipsa': {
    label: 'RBNZ IPSA',
    author: 'Reserve Bank of New Zealand',
    title: 'Review of the Insurance (Prudential Supervision) Act 2010',
    venue: 'Reserve Bank of New Zealand. Cabinet decisions 2025; Exposure Draft Q1 2026; consultation closes 7 July 2026; substantive provisions targeted 2028.',
    year: 2026,
    url: 'https://www.rbnz.govt.nz/regulation-and-supervision/oversight-of-insurers/how-we-regulate-and-supervise-insurers/our-policy-work-for-insurer-oversight/review-of-insurance-prudential-supervision-act-2010',
    significance: 'The current regulatory framework governing NZ-licensed insurers. Reform introduces a two-tier solvency framework (Prescribed Capital Requirement ceiling, Minimum Capital Requirement floor) with a graduated risk-based "ladder of intervention". The 2028 commencement creates a defined regulatory window for inverse-design tooling.',
  },

  /* ───── Market-size anchors ───── */
  'icnz-niwe-2025': {
    label: 'ICNZ NIWE 2025',
    author: 'Insurance Council of New Zealand',
    title: 'North Island Weather Events: The Insurance Industry Response',
    venue: 'Insurance Council of New Zealand, February 2025.',
    year: 2025,
    url: 'https://www.icnz.org.nz/wp-content/uploads/2025/02/ICNZ-NIWE-REPORT-FINAL-1.pdf',
    significance: 'Finalised insured-loss report for the combined 2023 Auckland Anniversary Floods and Cyclone Gabrielle: NZD 3.8 billion across 118,000+ private claims. Single largest weather-driven insured loss in NZ history. Used as the "Historical NZ Tail Event" benchmark in the Cascade scenarios chart on this page.',
  },
  'swissre-sigma-2025': {
    label: 'Swiss Re sigma 03/2025',
    author: 'Swiss Re Institute',
    title: 'sigma 03/2025: Property and casualty insurance: growing stronger in a riskier world',
    venue: 'Swiss Re Institute (2025).',
    year: 2025,
    url: 'https://www.swissre.com/institute/research/sigma-research/sigma-2025-03-property-casualty-growing-stronger-riskier-world.html',
    significance: 'Global property and casualty insurance market sized at USD 2.4 trillion (doubled over the past 20 years). Anchor for global commercial-line and reinsurance market sizing.',
  },
  'analytics-tam-2025': {
    label: 'Insurance Analytics TAM 2025',
    author: 'MarketsAndMarkets / ValueMomentum (composite)',
    title: 'Global insurance analytics market sizing',
    venue: 'MarketsAndMarkets and ValueMomentum, 2025.',
    year: 2025,
    url: 'https://www.marketsandmarkets.com/Market-Reports/insurance-analytics-market-227875309.html',
    significance: 'Mid-band positioning for an insurance analytics platform: USD 26.2 billion in 2025, USD 53.3 billion projected for 2030, CAGR 15.3%. Cat-modelling-software-only ($2B niche) is the beachhead segment, not the TAM ceiling.',
  },
  'artemis-ils-2025': {
    label: 'Artemis / Swiss Re ILS Insights',
    author: 'Artemis.bm and Swiss Re Institute',
    title: 'Catastrophe bond and ILS market data',
    venue: 'Artemis.bm and Swiss Re ILS Insights Edition XXXVII (February 2025).',
    year: 2025,
    url: 'https://www.artemis.bm/news/cat-bond-market-expansion-and-attractive-private-ils-opportunities-lay-ahead-hcma/',
    significance: 'Total ILS alternative capital approximately USD 121 billion (twelve months to June 2025). Catastrophe bonds outstanding USD 61.3 billion (end-2025, record year). Bermuda and Cayman Islands remain the primary structuring domiciles.',
  },

  /* ───── Industry rebrands ───── */
  'allianz-trade-rebrand': {
    label: 'Allianz Trade rebrand',
    author: 'Allianz',
    title: 'Euler Hermes is now Allianz Trade',
    venue: 'Allianz, 28 March 2022.',
    year: 2022,
    url: 'https://www.allianz.com/en/mediacenter/news/business/insurance/220328_Allianz-Euler-Hermes-is-now-Allianz-Trade.html',
    significance: 'Euler Hermes rebranded to Allianz Trade on 28 March 2022, completing the integration with Allianz Group (full ownership since 2018). Allianz Trade remains the world\'s leading trade credit insurer.',
  },

  /* ───── Marsden Point ───── */
  'rnz-marsden-2022': {
    label: 'RNZ Marsden Point 2022',
    author: 'RNZ',
    title: 'Refining NZ confirms Marsden Point switch to import-only terminal from April 2022',
    venue: 'RNZ News, 26 January 2022.',
    year: 2022,
    url: 'https://www.rnz.co.nz/news/business/456277/refining-nz-confirms-marsden-point-switch-to-import-only-terminal-from-april-2022',
    significance: 'Refining ended 31 March 2022; plant decommissioned April 2022; entity rebranded to Channel Infrastructure as an import-only terminal. As of May 2026, four years and one month of stranded refining exposure.',
  },
};

function formatRefBracket(label) {
  return '[Ref: ' + label + ']';
}

function CitationBadge({ refKey }) {
  const [open, setOpen] = React.useState(false);
  const c = CITATIONS[refKey];
  if (!c) {
    if (typeof console !== 'undefined') console.warn('[CitationBadge] missing refKey:', refKey);
    return null;
  }

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [open]);

  const drawer = open ? (
    <div className="cite-backdrop" onClick={() => setOpen(false)} role="presentation">
      <div className="cite-drawer"
           role="dialog"
           aria-label={'Citation: ' + c.label}
           onClick={(e) => e.stopPropagation()}>
        <button className="cite-close" aria-label="Close citation panel" onClick={() => setOpen(false)}>×</button>

        <div className="cite-eyebrow">Citation</div>
        <div className="cite-title">{c.title}</div>
        <div className="cite-author">{c.author} ({c.year})</div>
        <div className="cite-venue">{c.venue}</div>

        <div className="cite-rule" />

        {c.doi ? (
          <div className="cite-meta">
            <span className="cite-meta-key">DOI</span>
            <span className="cite-meta-val mono">{c.doi}</span>
          </div>
        ) : null}
        {c.url ? (
          <div className="cite-meta">
            <span className="cite-meta-key">URL</span>
            <a className="cite-meta-link" href={c.url} target="_blank" rel="noopener noreferrer">{c.url}</a>
          </div>
        ) : null}
        {c.open_access ? (
          <div className="cite-meta">
            <span className="cite-meta-key">PDF</span>
            <a className="cite-meta-link" href={c.open_access} target="_blank" rel="noopener noreferrer">{c.open_access}</a>
          </div>
        ) : null}

        <div className="cite-rule" />

        <div className="cite-eyebrow">Why this is cited here</div>
        <div className="cite-significance">{c.significance}</div>

        <div className="cite-footer">
          <span className="mono">Verification Ledger 2026-05-05 (Delta), Section III.</span>
        </div>
      </div>
    </div>
  ) : null;

  return (
    <React.Fragment>
      <button className="cite-badge"
              type="button"
              aria-label={'Open citation: ' + c.label}
              onClick={(e) => { e.stopPropagation(); setOpen(true); }}>
        {formatRefBracket(c.label)}
      </button>
      {drawer && ReactDOM.createPortal ? ReactDOM.createPortal(drawer, document.body) : drawer}
    </React.Fragment>
  );
}

window.CitationBadge = CitationBadge;
window.CITATIONS = CITATIONS;
