'use client'

import { useCallback, useEffect, useState } from 'react'
import Link from 'next/link'

import { useI18n } from '@/components/providers/i18n-provider'
import { RiskDelta, RiskGauge } from '@/components/charts/risk-gauge'
import { TimeSeriesChart } from '@/components/charts/time-series'
import { Wordmark } from '@/components/brand/logo'
import { CascadeTree } from '@/components/intelligence/cascade-tree'
import { EvidenceChain } from '@/components/intelligence/evidence-chain'
import { ParetoExplorer } from '@/components/intelligence/pareto-explorer'
import {
  OperatingEnvelopePanel,
  PhysicsValidationPanel,
} from '@/components/intelligence/physics-panel'
import { SimilarDecisions } from '@/components/intelligence/similar-decisions'
import { UncertaintyPanel } from '@/components/intelligence/uncertainty-panel'
import { Button, Notice } from '@/components/ui/controls'
import {
  Badge,
  DemoDataBadge,
  KeyValue,
  Meter,
  Panel,
  PanelBody,
  PanelHeader,
  StatCard,
  StateBadge,
} from '@/components/ui/display'
import { ApiClientError, api, failureMessage } from '@/lib/api/client'
import { cn } from '@/lib/cn'
import { formatNumber } from '@/lib/i18n/translate'
import { CHART_COLORS, styleForRisk } from '@/lib/ui/state-styles'
import type { DemoState } from '@/lib/services/demo-service'

/**
 * The presentation surface (§29, §52).
 *
 * Navigation and administrative chrome are gone; what remains is the story and a Next
 * button. Each stage's numbers are fetched from the server, which recomputes them from
 * the engines — so if a judge asks "is that a real calculation?", pressing Previous and
 * Next again re-derives it in front of them.
 */
export function DemoRunner({ initial }: { initial: DemoState }) {
  const { t, locale, n, mw, dateTime } = useI18n()

  const [state, setState] = useState<DemoState>(initial)
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const control = useCallback(
    async (action: 'start' | 'next' | 'previous' | 'goto' | 'reset', stage?: number) => {
      if (busy) return
      setBusy(true)
      setError(null)
      try {
        const params = new URLSearchParams({ stage: String(state.stage.index) })
        if (state.runCode) params.set('run', state.runCode)
        setState(await api.post<DemoState>(`/api/demo?${params.toString()}`, { action, stage }))
      } catch (caught) {
        setError(
          caught instanceof ApiClientError
            ? failureMessage(caught.failure, locale)
            : t('common.serverError'),
        )
      } finally {
        setBusy(false)
      }
    },
    [busy, state.stage.index, state.runCode, locale, t],
  )

  // Arrow keys drive the deck, so a presenter can use a clicker.
  useEffect(() => {
    const onKey = (event: KeyboardEvent) => {
      if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) return
      const forward = document.dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight'
      const back = document.dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft'
      if (event.key === forward || event.key === 'PageDown' || event.key === ' ') {
        event.preventDefault()
        void control('next')
      } else if (event.key === back || event.key === 'PageUp') {
        event.preventDefault()
        void control('previous')
      }
    }
    window.addEventListener('keydown', onKey)
    return () => window.removeEventListener('keydown', onKey)
  }, [control])

  const { stage, asset, grid } = state
  const isLast = stage.index >= state.stageCount

  return (
    <div className="min-h-dvh bg-base">
      <div className="nabdh-grid-bg nabdh-radial pointer-events-none fixed inset-0" aria-hidden />

      <div className="relative mx-auto max-w-7xl px-4 py-6 sm:px-6">
        {/* ── Header ────────────────────────────────────────────────────── */}
        <header className="flex flex-wrap items-center justify-between gap-4">
          <Wordmark locale={locale} />
          <div className="flex flex-wrap items-center gap-2">
            <DemoDataBadge label={t('common.simulatedFull')} title={t('demo.clockNote')} />
            <Badge tone="info">
              {t('demo.virtualTime')}: {dateTime(state.virtualTs)}
            </Badge>
            <Link
              href="/command-center"
              className="rounded-lg border border-border px-3 py-1.5 text-xs text-text-muted transition-colors hover:text-text"
            >
              {t('demo.exit')}
            </Link>
          </div>
        </header>

        {/* ── Stage progress ────────────────────────────────────────────── */}
        <nav aria-label={t('demo.title')} className="mt-6">
          <ol className="flex flex-wrap gap-1.5">
            {Array.from({ length: state.stageCount }, (_, index) => index + 1).map((step) => (
              <li key={step} className="flex-1">
                <button
                  type="button"
                  onClick={() => control('goto', step)}
                  disabled={busy}
                  aria-current={step === stage.index ? 'step' : undefined}
                  aria-label={t('demo.stage', { current: step, total: state.stageCount })}
                  className={cn(
                    'h-1.5 w-full rounded-full transition-colors',
                    step < stage.index
                      ? 'bg-brand/50'
                      : step === stage.index
                        ? 'bg-brand'
                        : 'bg-surface-3 hover:bg-border-strong',
                  )}
                />
              </li>
            ))}
          </ol>
          <p className="mt-2 text-[11px] text-text-faint">
            {t('demo.stage', { current: stage.index, total: state.stageCount })}
          </p>
        </nav>

        {/* ── Narration ─────────────────────────────────────────────────── */}
        <section className="mt-4">
          <h1 className="text-2xl font-semibold tracking-tight text-text sm:text-3xl">
            {locale === 'ar' ? stage.titleAr : stage.title}
          </h1>
          <p className="mt-2 max-w-4xl text-sm leading-relaxed text-text-muted sm:text-base">
            {locale === 'ar' ? stage.narrationAr : stage.narration}
          </p>
        </section>

        {error ? <Notice tone="danger" className="mt-4">{error}</Notice> : null}

        {/* ── Always-visible vitals ─────────────────────────────────────── */}
        <div className="mt-6 grid gap-3 sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-6">
          <Vital
            label={t('assets.columns.load')}
            value={`${n(asset.loadPct, { maximumFractionDigits: 1 })}%`}
            hint={`${mw(asset.loadMw)} / ${mw(asset.capacityMw)} ${t('common.units.mw')}`}
            alert={asset.loadPct >= 90}
          />
          <Vital
            label={t('assets.columns.temperature')}
            value={`${n(asset.tempC, { maximumFractionDigits: 1 })}${t('common.units.celsius')}`}
            hint={`${t('assets.passport.ratedTemp')} ${n(asset.ratedTempC)}`}
            alert={asset.tempC >= asset.ratedTempC}
          />
          <Vital
            label={t('grid.electrical.voltage')}
            value={`${n(asset.voltageKv, { maximumFractionDigits: 2 })} ${t('common.units.kv')}`}
          />
          <Vital
            label={t('commandCenter.frequency')}
            value={`${n(asset.frequencyHz, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${t('common.units.hz')}`}
          />
          <Vital
            label={t('grid.columns.temperature')}
            value={`${n(grid.ambientC, { maximumFractionDigits: 1 })}${t('common.units.celsius')}`}
            hint={locale === 'ar' ? asset.regionNameAr : asset.regionName}
          />
          <Vital
            label={t('common.riskScore')}
            value={`${n(asset.riskScore, { maximumFractionDigits: 0 })}%`}
            alert={asset.riskScore >= 70}
            emphasis
          />
        </div>

        {/* ── Focus panel ───────────────────────────────────────────────── */}
        {/* A minimum height keeps the control bar in the same place from stage to stage;
            without it the page reflows under the presenter's cursor on every click. */}
        <div className="mt-6 min-h-[22rem]">
          <FocusPanel state={state} />
        </div>

        {/* ── Controls ──────────────────────────────────────────────────── */}
        <div className="sticky bottom-4 mt-8 flex flex-wrap items-center justify-between gap-3 rounded-[--radius-panel] border border-border bg-surface/90 px-4 py-3 backdrop-blur-xl">
          <div className="flex items-center gap-2">
            <Button
              variant="ghost"
              onClick={() => control('previous')}
              disabled={busy || stage.index <= 1}
            >
              ← {t('demo.previous')}
            </Button>
            <Button variant="ghost" onClick={() => control('reset')} disabled={busy}>
              {t('demo.restart')}
            </Button>
          </div>

          <Button size="lg" onClick={() => control('next')} loading={busy} disabled={isLast}>
            {isLast ? t('demo.prevented.title') : t('demo.next')} →
          </Button>
        </div>

        <p className="mt-4 pb-6 text-center text-[11px] leading-relaxed text-text-faint">
          {t('demo.clockNote')}
        </p>
      </div>
    </div>
  )
}

function Vital({
  label,
  value,
  hint,
  alert = false,
  emphasis = false,
}: {
  label: string
  value: string
  hint?: string
  alert?: boolean
  emphasis?: boolean
}) {
  return (
    <div
      className={cn(
        'rounded-[--radius-panel] border px-4 py-3 transition-colors',
        alert ? 'border-critical/40 bg-critical/8' : 'border-border bg-surface/60',
      )}
    >
      <p className="text-[10px] uppercase tracking-wide text-text-faint">{label}</p>
      <p
        className={cn(
          'tnum mt-1 font-semibold',
          emphasis ? 'text-3xl' : 'text-xl',
          alert ? 'text-critical' : 'text-text',
        )}
      >
        {value}
      </p>
      {hint ? <p className="mt-0.5 text-[10px] text-text-faint">{hint}</p> : null}
    </div>
  )
}

function FocusPanel({ state }: { state: DemoState }) {
  const { t, locale, n, mw, time, duration } = useI18n()
  const {
    stage,
    asset,
    grid,
    prediction,
    strategy,
    impact,
    comparison,
    dnaMatches,
    actions,
    weakSignals,
    rootCause,
    cascade,
    counterfactual,
    strategies,
    branches,
    envelope,
    physics,
    uncertainty,
    cascadeTree,
    breakpoints,
    similar,
    evidence,
    verification,
    sources,
    hunt,
    replay,
  } = state
  const ar = locale === 'ar'

  switch (stage.focus) {
    // ── 2.0 stages ────────────────────────────────────────────────────────
    case 'weak_signal':
      return (
        <Panel>
          <PanelHeader
            title={t('weakSignals.title')}
            subtitle={t('weakSignals.subtitle')}
            action={
              <Badge tone={weakSignals.isPattern ? 'accent' : 'muted'}>
                {weakSignals.isPattern ? t('weakSignals.patternFound') : t('weakSignals.noPattern')}
              </Badge>
            }
          />
          <PanelBody>
            <Meter
              value={weakSignals.combinedScore}
              state={weakSignals.combinedScore >= 70 ? 'critical' : weakSignals.combinedScore >= 45 ? 'warning' : 'watch'}
              label={t('weakSignals.combined')}
              showValue
            />
            <ul className="mt-4 space-y-2">
              {weakSignals.signals.map((signal) => (
                <li key={signal.key} className="flex items-baseline justify-between gap-3 text-xs">
                  <span className="text-text-muted">{t(`weakSignals.key.${signal.key}`)}</span>
                  <span
                    className={cn(
                      'tnum font-medium',
                      signal.isIndividuallyCritical
                        ? 'text-critical'
                        : signal.deviationPct > 0
                          ? 'text-watch'
                          : 'text-normal',
                    )}
                  >
                    {signal.deviationPct > 0 ? '+' : ''}
                    {n(signal.deviationPct, { maximumFractionDigits: 1 })}%
                    <span className="ms-2 text-[10px] text-text-faint">
                      {t('weakSignals.threshold')} {n(signal.individualThresholdPct)}%
                    </span>
                  </span>
                </li>
              ))}
            </ul>
            <p
              className={cn(
                'mt-4 rounded-lg border px-3 py-2 text-[11px] leading-relaxed',
                weakSignals.traditionalAlarm
                  ? 'border-critical/30 bg-critical/8 text-critical'
                  : 'border-brand/30 bg-brand/8 text-brand',
              )}
            >
              {weakSignals.traditionalAlarm
                ? t('weakSignals.traditionalSounding')
                : t('weakSignals.traditionalSilent')}
            </p>
          </PanelBody>
        </Panel>
      )

    case 'root_cause':
      return (
        <Panel>
          <PanelHeader
            title={t('rootCause.title')}
            subtitle={ar ? rootCause.summaryAr : rootCause.summary}
            action={
              <Badge tone="brand">{n(rootCause.confidence, { maximumFractionDigits: 0 })}%</Badge>
            }
          />
          <PanelBody>
            <ol className="space-y-2.5">
              {rootCause.chain.map((link, index) => (
                <li key={`${link.stage}-${link.key}-${index}`} className="flex items-start gap-2.5">
                  <span className="mt-0.5 inline-flex w-20 shrink-0 justify-center rounded-full border border-border-strong bg-surface-2 px-2 py-0.5 text-[10px] font-medium text-text-muted">
                    {t(`rootCause.stage.${link.stage}`)}
                  </span>
                  <div className="min-w-0">
                    <p className="text-xs font-medium text-text">{ar ? link.labelAr : link.label}</p>
                    <p className="mt-0.5 text-[11px] leading-relaxed text-text-muted">
                      {ar ? link.detailAr : link.detail}
                    </p>
                  </div>
                </li>
              ))}
            </ol>
          </PanelBody>
        </Panel>
      )

    case 'cascade':
      return (
        <Panel>
          <PanelHeader
            title={t('cascade.timeline')}
            subtitle={`${t('cascade.affectedCustomers')}: ${n(cascade.affectedCustomers)}`}
            action={
              <Badge tone="accent">
                {t('cascade.depth')} {n(cascade.maxDepth)}
              </Badge>
            }
          />
          <PanelBody>
            {cascade.steps.filter((step) => step.depth > 0).length === 0 ? (
              <p className="text-xs text-text-muted">{t('cascade.empty')}</p>
            ) : (
              <ol className="space-y-2.5">
                {cascade.steps.map((step) => (
                  <li
                    key={`${step.ordinal}-${step.assetCode}`}
                    className="flex items-baseline gap-3 text-xs"
                  >
                    <span className="tnum w-12 shrink-0 text-end font-medium text-text-faint">
                      +{n(step.offsetMin)}
                    </span>
                    <span className="font-mono text-text">{step.assetCode}</span>
                    <span className="text-text-muted">
                      {t(`cascade.mechanism.${step.mechanism}`)}
                    </span>
                    <span className="tnum ms-auto text-text-faint">
                      {n(step.loadPctAfter, { maximumFractionDigits: 0 })}% ·{' '}
                      {n(step.probability * 100, { maximumFractionDigits: 0 })}%
                    </span>
                  </li>
                ))}
              </ol>
            )}
          </PanelBody>
        </Panel>
      )

    case 'counterfactual':
      return (
        <Panel>
          <PanelHeader
            title={t('counterfactual.minimum')}
            subtitle={t('counterfactual.pruningHint')}
            action={
              <Badge tone={counterfactual.achieved ? 'brand' : 'accent'}>
                {counterfactual.achieved
                  ? t('counterfactual.achieved')
                  : t('counterfactual.notAchieved')}
              </Badge>
            }
          />
          <PanelBody>
            <div className="flex flex-wrap items-baseline gap-x-6 gap-y-2 border-b border-border/70 pb-3">
              <div>
                <p className="text-[10px] uppercase tracking-wide text-text-faint">
                  {t('counterfactual.before')}
                </p>
                <p className="tnum text-2xl font-semibold text-critical">
                  {n(counterfactual.riskBefore, { maximumFractionDigits: 1 })}%
                </p>
              </div>
              <span aria-hidden className="text-text-faint">
                →
              </span>
              <div>
                <p className="text-[10px] uppercase tracking-wide text-text-faint">
                  {t('counterfactual.after')}
                </p>
                <p className="tnum text-2xl font-semibold text-normal">
                  {n(counterfactual.riskAfter, { maximumFractionDigits: 1 })}%
                </p>
              </div>
            </div>
            <ul className="mt-3 space-y-2">
              {counterfactual.doses.map((dose) => (
                <li key={dose.key} className="flex items-baseline justify-between gap-3 text-xs">
                  <span className="text-text">{ar ? dose.labelAr : dose.label}</span>
                  <span className="tnum shrink-0 text-normal">
                    −{n(dose.contribution, { maximumFractionDigits: 1 })}
                  </span>
                </li>
              ))}
            </ul>
          </PanelBody>
        </Panel>
      )

    case 'strategies':
      return (
        <Panel>
          <PanelHeader
            title={t('selfHealing.title')}
            subtitle={t('selfHealing.subtitle')}
            action={<Badge tone="accent">{t('common.simulationOnly')}</Badge>}
          />
          <PanelBody className="space-y-2.5">
            {strategies.map((candidate) => (
              <div
                key={candidate.key}
                className={cn(
                  'rounded-lg border p-3',
                  candidate.isRecommended ? 'border-brand/45 bg-brand/6' : 'border-border bg-surface-2/40',
                )}
              >
                <div className="flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1">
                  <p className="text-xs font-medium text-text">
                    <span className="tnum me-2 text-[10px] text-text-faint">#{candidate.rank}</span>
                    {ar ? candidate.labelAr : candidate.label}
                  </p>
                  <p className="tnum text-xs text-text-muted">
                    <span className="text-critical">
                      {n(candidate.evaluation.riskBefore, { maximumFractionDigits: 0 })}%
                    </span>
                    {' → '}
                    <span className="text-normal">
                      {n(candidate.evaluation.riskAfter, { maximumFractionDigits: 0 })}%
                    </span>
                    <span className="ms-3 text-text-faint">
                      {t('selfHealing.score')} {n(candidate.score, { maximumFractionDigits: 1 })}
                    </span>
                  </p>
                </div>
              </div>
            ))}
          </PanelBody>
        </Panel>
      )

    case 'grid':
      return (
        <Panel>
          <PanelHeader
            title={t('commandCenter.title')}
            action={
              <StateBadge
                state={grid.regionState}
                label={t(`states.${grid.regionState}`)}
                pulse={grid.regionPeakRisk >= 70}
              />
            }
          />
          <PanelBody>
            <dl className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
              <KeyValue
                label={t('commandCenter.cards.totalLoad')}
                value={`${mw(grid.totalLoadMw)} ${t('common.units.mw')}`}
                mono
              />
              <KeyValue
                label={locale === 'ar' ? asset.regionNameAr : asset.regionName}
                value={`${mw(grid.regionLoadMw)} ${t('common.units.mw')}`}
                mono
              />
              <KeyValue
                label={t('commandCenter.cards.gridStability')}
                value={n(grid.stabilityIndex, { maximumFractionDigits: 1 })}
                mono
              />
              <KeyValue
                label={t('commandCenter.cards.criticalAssets')}
                value={n(grid.assetsAtRisk)}
                mono
              />
            </dl>
            <Meter
              value={grid.regionPeakRisk}
              state={grid.regionState}
              className="mt-5"
              label={t('grid.columns.peakRisk')}
              showValue
            />
          </PanelBody>
        </Panel>
      )

    case 'asset':
      return (
        <Panel>
          <PanelHeader
            title={`${asset.code} · ${locale === 'ar' ? asset.nameAr : asset.name}`}
            subtitle={locale === 'ar' ? asset.regionNameAr : asset.regionName}
          />
          <PanelBody className="grid gap-6 lg:grid-cols-[240px_1fr]">
            <div className="flex justify-center">
              <RiskGauge value={asset.riskScore} />
            </div>
            <dl className="grid gap-x-8 gap-y-1 sm:grid-cols-2">
              <KeyValue
                label={t('assets.columns.load')}
                value={`${n(asset.loadPct, { maximumFractionDigits: 1 })}%`}
                mono
              />
              <KeyValue
                label={t('assets.columns.temperature')}
                value={`${n(asset.tempC, { maximumFractionDigits: 1 })} ${t('common.units.celsius')}`}
                mono
              />
              <KeyValue
                label={t('assets.passport.currentHealth')}
                value={n(asset.effectiveHealth, { maximumFractionDigits: 0 })}
                mono
              />
              <KeyValue
                label={t('assets.passport.customers')}
                value={n(asset.customersServed)}
                mono
              />
              <KeyValue
                label={t('grid.electrical.voltage')}
                value={`${n(asset.voltageKv, { maximumFractionDigits: 2 })} ${t('common.units.kv')}`}
                mono
              />
              <KeyValue
                label={t('grid.columns.temperature')}
                value={`${n(asset.ambientC, { maximumFractionDigits: 1 })} ${t('common.units.celsius')}`}
                mono
              />
            </dl>
          </PanelBody>
        </Panel>
      )

    case 'dna': {
      const top = dnaMatches[0]
      if (!top) return null
      return (
        <Panel glow>
          <PanelHeader
            title={t('dna.topMatches')}
            subtitle={t('dna.howItWorksBody')}
            action={
              <span className={cn('tnum text-3xl font-semibold', styleForRisk(top.similarity).text)}>
                {n(top.similarity, { maximumFractionDigits: 0 })}%
              </span>
            }
          />
          <PanelBody>
            <div className="mb-4 flex flex-wrap items-center gap-2">
              <Badge tone="brand">{top.code}</Badge>
              <span className="text-sm font-medium text-text">
                {locale === 'ar' ? top.nameAr : top.name}
              </span>
              <Badge tone="muted">{t(`eventType.${top.eventType}`)}</Badge>
            </div>

            <div className="space-y-2">
              {top.contributions.map((entry) => (
                <div key={entry.feature} className="flex items-center gap-3">
                  <span className="w-36 shrink-0 truncate text-[11px] text-text-muted">
                    {t(`dnaFeature.${entry.feature}`)}
                  </span>
                  <div className="relative h-4 flex-1 overflow-hidden rounded bg-surface-3">
                    <div
                      className="absolute inset-y-0 rounded bg-info/45"
                      style={{ insetInlineStart: 0, width: `${entry.historical * 100}%` }}
                    />
                    <div
                      className="absolute inset-y-1 rounded bg-brand"
                      style={{ insetInlineStart: 0, width: `${entry.current * 100}%` }}
                    />
                  </div>
                  <span
                    className={cn(
                      'tnum w-12 shrink-0 text-end text-[11px] font-medium',
                      entry.agreement >= 85 ? 'text-normal' : entry.agreement >= 60 ? 'text-watch' : 'text-text-faint',
                    )}
                  >
                    {n(entry.agreement, { maximumFractionDigits: 0 })}%
                  </span>
                </div>
              ))}
            </div>

            <ul className="mt-4 flex flex-wrap gap-2 border-t border-border pt-3">
              {dnaMatches.slice(1).map((match) => (
                <li key={match.code} className="text-[11px] text-text-muted">
                  <span className="font-mono">{match.code}</span> ·{' '}
                  {n(match.similarity, { maximumFractionDigits: 0 })}%
                </li>
              ))}
            </ul>
          </PanelBody>
        </Panel>
      )
    }

    case 'prediction':
      return (
        <Panel glow>
          <PanelHeader title={t('predictions.title')} subtitle={t('timeMachine.note')} />
          <PanelBody className="grid gap-6 lg:grid-cols-[240px_1fr]">
            <div className="flex justify-center">
              <RiskGauge value={asset.riskScore} label={t('common.riskScore')} />
            </div>
            <dl className="grid gap-4 sm:grid-cols-2">
              <BigStat
                label={t('predictions.columns.event')}
                value={t(`eventType.${prediction.eventType}`)}
              />
              <BigStat
                label={t('predictions.columns.eta')}
                value={
                  prediction.etaMinutes !== null
                    ? duration(prediction.etaMinutes)
                    : t('predictions.etaNone')
                }
                accent
              />
              <BigStat
                label={t('common.probability')}
                value={`${n(prediction.probability * 100, { maximumFractionDigits: 0 })}%`}
              />
              <BigStat
                label={t('common.confidence')}
                value={`${n(prediction.confidence * 100, { maximumFractionDigits: 0 })}%`}
              />
              {prediction.etaAt ? (
                <BigStat
                  label={t('timeMachine.breachAt', { time: '' }).trim()}
                  value={time(prediction.etaAt)}
                />
              ) : null}
              {prediction.breachReason ? (
                <BigStat
                  label={t('predictions.columns.event')}
                  value={t(`predictions.breachReason.${prediction.breachReason}`)}
                />
              ) : null}
            </dl>
          </PanelBody>
        </Panel>
      )

    case 'explain': {
      const factors = asset.risk.topFactors.filter((factor) => factor.contribution > 0.05)
      const max = Math.max(...factors.map((factor) => factor.contribution), 1)
      return (
        <Panel glow>
          <PanelHeader
            title={t('predictions.explain.title')}
            subtitle={t('predictions.explain.subtitle')}
            action={
              <span className={cn('tnum text-3xl font-semibold', styleForRisk(asset.riskScore).text)}>
                {n(asset.riskScore, { maximumFractionDigits: 0 })}%
              </span>
            }
          />
          <PanelBody>
            <ul className="space-y-3">
              {factors.map((factor) => (
                <li key={factor.key}>
                  <div className="flex items-baseline justify-between gap-3">
                    <span className="text-sm text-text">{t(`riskFactor.${factor.key}`)}</span>
                    <span className="tnum text-sm font-semibold text-brand">
                      +{n(factor.contribution, { maximumFractionDigits: 1 })}
                    </span>
                  </div>
                  <div className="mt-1.5 h-2 overflow-hidden rounded-full bg-surface-3">
                    <div
                      className="h-full rounded-full bg-gradient-to-r from-brand/50 to-brand transition-[width] duration-700"
                      style={{ width: `${(factor.contribution / max) * 100}%` }}
                    />
                  </div>
                </li>
              ))}
            </ul>
            <p className="mt-5 rounded-lg border border-border bg-surface-2/50 p-4 text-sm leading-relaxed text-text">
              {prediction.narrative}
            </p>
          </PanelBody>
        </Panel>
      )
    }

    case 'time_machine':
      return (
        <Panel glow>
          <PanelHeader title={t('timeMachine.title')} subtitle={t('timeMachine.note')} />
          <PanelBody>
            <TimeSeriesChart
              data={prediction.trajectory.map((frame, index) => ({
                ts: frame.ts,
                risk: frame.risk,
                mitigated: prediction.mitigated?.[index]?.risk ?? null,
              }))}
              height={300}
              yDomain={[0, 100]}
              ariaLabel={t('timeMachine.trajectory')}
              valueFormatter={(value) => `${n(value, { maximumFractionDigits: 0 })}%`}
              markers={
                prediction.etaAt
                  ? [
                      {
                        x: prediction.etaAt,
                        label: t('incidents.replay.failure'),
                        color: CHART_COLORS.danger,
                      },
                    ]
                  : undefined
              }
              series={[
                {
                  key: 'risk',
                  label: t('timeMachine.withoutAction'),
                  color: CHART_COLORS.danger,
                  type: 'area',
                },
                {
                  key: 'mitigated',
                  label: t('timeMachine.withAction'),
                  color: CHART_COLORS.primary,
                  type: 'line',
                },
              ]}
            />
          </PanelBody>
        </Panel>
      )

    case 'recommendations':
      return (
        <Panel glow>
          <PanelHeader
            title={t('recommendations.title')}
            subtitle={t('recommendations.subtitle')}
          />
          <PanelBody>
            <ul className="space-y-2">
              {actions
                .filter((action) => action.riskReduction > 0.05)
                .map((action) => (
                  <li
                    key={action.key}
                    className={cn(
                      'flex flex-wrap items-center gap-4 rounded-lg border p-4',
                      strategy.chosen.includes(action.key)
                        ? 'border-brand/45 bg-brand/8'
                        : 'border-border bg-surface-2/40',
                    )}
                  >
                    <div className="min-w-0 flex-1">
                      <div className="flex flex-wrap items-center gap-2">
                        <Badge tone="neutral">{t(`actionType.${action.actionType}`)}</Badge>
                        {strategy.chosen.includes(action.key) ? (
                          <Badge tone="brand">{t('recommendations.combined')}</Badge>
                        ) : null}
                      </div>
                      <p className="mt-1.5 text-sm text-text">
                        {locale === 'ar' ? action.titleAr : action.title}
                      </p>
                    </div>
                    <div className="text-end">
                      <p className="text-[10px] uppercase tracking-wide text-text-faint">
                        {t('recommendations.expectedReduction')}
                      </p>
                      <p className="tnum text-2xl font-semibold text-brand">
                        −{n(action.riskReduction, { maximumFractionDigits: 1 })}
                      </p>
                    </div>
                  </li>
                ))}
            </ul>
          </PanelBody>
        </Panel>
      )

    case 'simulation':
      return (
        <Panel glow>
          <PanelHeader
            title={t('simulations.comparison.title')}
            subtitle={t('recommendations.combinedNote')}
          />
          <PanelBody className="space-y-5">
            <RiskDelta
              before={strategy.riskBefore}
              after={strategy.riskAfter}
              beforeLabel={t('simulations.comparison.noAction')}
              afterLabel={t('simulations.comparison.aiStrategy')}
              note={t('timeMachine.note')}
            />
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <caption className="sr-only">{t('simulations.comparison.title')}</caption>
                <thead>
                  <tr className="border-b border-border text-[11px] uppercase tracking-wide text-text-faint">
                    <th scope="col" className="px-3 py-2 text-start">{t('common.scenario')}</th>
                    <th scope="col" className="px-3 py-2 text-end">{t('common.riskScore')}</th>
                    <th scope="col" className="px-3 py-2 text-end">{t('assets.columns.load')}</th>
                    <th scope="col" className="px-3 py-2 text-end">{t('assets.columns.temperature')}</th>
                  </tr>
                </thead>
                <tbody>
                  {comparison.map((row) => (
                    <tr key={row.key} className="border-b border-border/60">
                      <td className="px-3 py-3 text-text">
                        {row.key === 'no_action'
                          ? t('simulations.comparison.noAction')
                          : row.key === 'ai_strategy'
                            ? t('simulations.comparison.aiStrategy')
                            : locale === 'ar'
                              ? row.labelAr
                              : row.label}
                      </td>
                      <td className={cn('tnum px-3 py-3 text-end text-lg font-semibold', styleForRisk(row.risk).text)}>
                        {n(row.risk, { maximumFractionDigits: 0 })}%
                      </td>
                      <td className="tnum px-3 py-3 text-end text-text-muted">
                        {n(row.loadPct, { maximumFractionDigits: 0 })}%
                      </td>
                      <td className="tnum px-3 py-3 text-end text-text-muted">
                        {n(row.tempC, { maximumFractionDigits: 0 })}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </PanelBody>
        </Panel>
      )

    // ── 4.0 acts (§105) ───────────────────────────────────────────────────
    case 'physics':
      return <OperatingEnvelopePanel envelope={envelope} />

    case 'uncertainty':
      return <UncertaintyPanel view={uncertainty} />

    case 'breakpoint':
      return (
        <CascadeTree
          tree={cascadeTree}
          breakpoints={breakpoints}
          contained={cascade.affectedAssets <= 1}
        />
      )

    case 'memory':
      return <SimilarDecisions matches={similar} />

    case 'pareto':
      return <ParetoExplorer assetCode={asset.code} initial={null} canRun />

    case 'validation':
      return (
        <PhysicsValidationPanel
          verdict={physics.verdict}
          checks={physics.checks}
          summary={physics.summary}
          summaryAr={physics.summaryAr}
          confidence={physics.confidence}
        />
      )

    case 'evidence':
      return evidence ? (
        <EvidenceChain bundle={evidence} />
      ) : (
        <Panel>
          <PanelHeader title={t('evidence.chainTitle')} />
          <PanelBody>
            <p className="text-[11px] text-text-muted">{t('uiState.empty')}</p>
          </PanelBody>
        </Panel>
      )

    case 'verification':
      return (
        <Panel>
          <PanelHeader
            title={t('verification.title')}
            subtitle={t('verification.subtitle')}
            action={
              <Badge tone={verification.underpowered ? 'muted' : 'brand'}>
                {verification.verified} {t('verification.verified').toLowerCase()}
              </Badge>
            }
          />
          <PanelBody className="space-y-3">
            <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
              <StatCard
                label={t('verification.verified')}
                value={`${verification.verified}`}
                hint={`${verification.pending} ${t('verification.pending').toLowerCase()}`}
              />
              <StatCard
                label={t('verification.meanError')}
                value={`${formatNumber(locale, verification.meanAbsPctError, { maximumFractionDigits: 2 })}%`}
              />
              <StatCard
                label={t('verification.coverage')}
                value={`${formatNumber(locale, verification.coveragePct, { maximumFractionDigits: 1 })}%`}
              />
              <StatCard
                label={t('verification.calibrationGap')}
                value={`${verification.calibrationGap >= 0 ? '+' : ''}${formatNumber(locale, verification.calibrationGap, { maximumFractionDigits: 1 })}`}
                hint={t('verification.calibrationHint')}
              />
            </div>
            <p className="text-[11px] leading-relaxed text-text-muted">
              {verification.underpowered
                ? t('verification.underpowered')
                : t('verification.calibrationHint')}
            </p>
          </PanelBody>
        </Panel>
      )

    case 'result':
      return (
        <div className="space-y-4">
          <Panel>
            <PanelHeader
              title={t('futures.title')}
              subtitle={t('futures.subtitle')}
              action={<Badge tone="accent">{t('futures.estimate')}</Badge>}
            />
            <PanelBody>
              <div className="grid gap-3 md:grid-cols-3">
                {branches.map((branch) => (
                  <div key={branch.key} className="rounded-lg border border-border bg-surface-2/40 p-3">
                    <p className="text-[10px] uppercase tracking-wide text-text-faint">
                      {t(`futures.${branch.key}`)}
                    </p>
                    <p
                      className={cn(
                        'tnum mt-1 text-2xl font-semibold',
                        branch.key === 'no_action'
                          ? 'text-critical'
                          : branch.key === 'operator_action'
                            ? 'text-watch'
                            : 'text-normal',
                      )}
                    >
                      {n(branch.risk, { maximumFractionDigits: 0 })}%
                    </p>
                    <p className="tnum mt-1 text-[11px] text-text-muted">
                      {t('futures.assets')} {n(branch.assetsAffected)} · {t('futures.downtime')}{' '}
                      {n(branch.potentialDowntimeMin)} {t('common.minutes')}
                    </p>
                  </div>
                ))}
              </div>
            </PanelBody>
          </Panel>

          <Panel glow>
          <PanelHeader title={t('demo.prevented.title')} subtitle={t('demo.prevented.note')} />
          <PanelBody className="space-y-6">
            <RiskDelta
              before={strategy.riskBefore}
              after={strategy.riskAfter}
              beforeLabel={t('simulations.comparison.noAction')}
              afterLabel={t('simulations.comparison.aiStrategy')}
            />

            <dl className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
              <BigStat
                label={t('demo.prevented.customersProtected')}
                value={n(impact.customersProtected)}
                accent
              />
              <BigStat
                label={t('demo.prevented.downtimeAvoided')}
                value={duration(impact.downtimeAvoidedMin)}
                accent
              />
              <BigStat
                label={t('demo.prevented.capacityProtected')}
                value={`${mw(impact.capacityProtectedMw)} ${t('common.units.mw')}`}
                accent
              />
              <BigStat
                label={t('demo.prevented.operationalImpact')}
                value={`${n(impact.economicImpactSar / 1_000_000, { maximumFractionDigits: 1 })} M ${t('common.units.sar')}`}
                accent
              />
            </dl>

            <Notice tone="warning">{t('demo.prevented.note')}</Notice>

            <div className="flex flex-wrap gap-3">
              <Link
                href="/command-center"
                className="rounded-lg bg-brand px-5 py-2.5 text-sm font-medium text-on-brand transition-colors hover:bg-brand/90"
              >
                {t('nav.commandCenter')}
              </Link>
              <Link
                href="/why-nabdh"
                className="rounded-lg border border-border-strong px-5 py-2.5 text-sm font-medium text-text transition-colors hover:bg-surface-2"
              >
                {t('why.title')}
              </Link>
            </div>
          </PanelBody>
        </Panel>
        </div>
      )

    // ── 4.1 stages ────────────────────────────────────────────────────────
    case 'sources':
      return (
        <Panel>
          <PanelHeader
            title={t('integrations.hub.title')}
            subtitle={t('integrations.hub.honesty')}
            action={
              <Badge tone="accent">
                {n(sources.demo)} {t('integrations.hub.modeDemo')}
              </Badge>
            }
          />
          <PanelBody className="space-y-3">
            <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
              <BigStat label={t('integrations.hub.sources')} value={n(sources.total)} />
              <BigStat
                label={t('integrations.hub.meanQuality')}
                value={`${n(sources.meanQuality, { maximumFractionDigits: 1 })}%`}
                accent
              />
              <BigStat
                label={t('integrations.hub.throughput')}
                value={n(sources.throughputPerMin, { maximumFractionDigits: 1 })}
              />
              <BigStat label={t('integrations.hub.disconnected')} value={n(sources.disconnected + sources.error)} />
            </div>

            {/* The label, not the status: mode and status together or not at all. */}
            <ul className="space-y-1.5">
              {sources.connectors.map((connector) => (
                <li
                  key={connector.code}
                  data-demo-connector={connector.label}
                  className="flex flex-wrap items-baseline justify-between gap-2 rounded-lg border border-border bg-surface-2/40 px-3 py-2 text-[11px]"
                >
                  <span>{ar ? connector.nameAr : connector.name}</span>
                  <span className="flex items-center gap-2">
                    <Badge tone={connector.status === 'connected' ? 'brand' : 'muted'}>
                      {connector.label === 'demo_connected'
                        ? t('integrations.hub.connected')
                        : connector.label === 'demo_degraded'
                          ? t('integrations.hub.degraded')
                          : t('integrations.hub.disconnected')}
                    </Badge>
                    <span className="tnum font-mono text-text-faint">
                      {n(connector.dataQuality, { maximumFractionDigits: 1 })}%
                    </span>
                  </span>
                </li>
              ))}
            </ul>
          </PanelBody>
        </Panel>
      )

    case 'hunt':
      return (
        <Panel>
          <PanelHeader
            title={t('riskHunter.title')}
            subtitle={ar ? hunt.summaryAr : hunt.summary}
            action={<Badge tone="accent">{t('riskHunter.simulatedBadge')}</Badge>}
          />
          <PanelBody className="space-y-3">
            <p className="text-[11px] leading-relaxed text-text-muted" data-demo-budget>
              {t('riskHunter.budget')
                .replace('{run}', n(hunt.simulationsRun))
                .replace('{budget}', n(hunt.budgetSimulations))
                .replace('{ms}', n(hunt.durationMs))}
              {'. '}
              <span className={hunt.budgetExhausted ? 'text-warning' : 'text-normal'}>
                {hunt.budgetExhausted ? t('riskHunter.exhausted') : t('riskHunter.complete')}
              </span>
            </p>

            {hunt.findings.length === 0 ? (
              <p className="text-[12px] text-text-muted">{t('riskHunter.noFindings')}</p>
            ) : (
              <ul className="space-y-2">
                {hunt.findings.slice(0, 3).map((finding) => (
                  <li
                    key={finding.code}
                    className="rounded-lg border border-border bg-surface-2/40 p-3"
                    data-demo-finding={finding.assetCode}
                  >
                    <p className="text-[12px] leading-relaxed">
                      {ar ? finding.narrativeAr : finding.narrative}
                    </p>
                    <div className="mt-2 flex flex-wrap gap-3 text-[11px] text-text-faint">
                      <span>
                        {t('riskHunter.novelty')}{' '}
                        <span className="tnum text-text">{n(finding.noveltyScore)}</span>
                      </span>
                      <span>
                        {t('riskHunter.plausibility')}{' '}
                        <span className="tnum text-text">{n(finding.probability)}%</span>
                      </span>
                      <span>
                        {t('riskHunter.cascadeRisk')}{' '}
                        <span className="tnum text-text">
                          {n(finding.cascadeProbability, { maximumFractionDigits: 1 })}%
                        </span>
                      </span>
                    </div>
                    {finding.prevention ? (
                      <p
                        className={cn(
                          'mt-2 text-[11px] font-medium',
                          finding.prevention.achieved ? 'text-normal' : 'text-watch',
                        )}
                      >
                        {finding.prevention.achieved
                          ? t('riskHunter.preventionAchieved')
                          : t('riskHunter.preventionPartial')}
                      </p>
                    ) : null}
                  </li>
                ))}
              </ul>
            )}
            <p className="text-[10px] leading-relaxed text-text-faint">{t('riskHunter.sandbox')}</p>
          </PanelBody>
        </Panel>
      )

    case 'replay':
      return (
        <Panel>
          <PanelHeader
            title={t('replay.title')}
            subtitle={t('replay.note')}
            action={
              replay.preventionWindowMin === null ? (
                <Badge tone="muted">{t('replay.noWindow')}</Badge>
              ) : (
                <Badge tone="brand" data-demo-window>
                  {t('replay.preventionWindow')}: {n(replay.preventionWindowMin)} min
                </Badge>
              )
            }
          />
          <PanelBody className="space-y-3">
            <ol className="space-y-1.5">
              {replay.frames.map((frame) => (
                <li
                  key={frame.seq}
                  data-demo-frame={frame.stage}
                  className="flex flex-wrap items-baseline justify-between gap-2 rounded-lg border border-border bg-surface-2/40 px-3 py-2 text-[11px]"
                >
                  <span>
                    <span className="me-2 font-mono text-text-faint">{frame.seq + 1}</span>
                    {ar ? frame.titleAr : frame.title}
                  </span>
                  <span className="flex items-center gap-2 font-mono tnum text-text-faint">
                    {t(`replay.stage.${frame.stage}`)} · {time(frame.ts)}
                  </span>
                </li>
              ))}
            </ol>

            {replay.simulatedOnly ? (
              <p className="rounded-lg border border-watch/30 bg-watch/8 px-3 py-2 text-[11px] leading-relaxed text-watch">
                {t('replay.syntheticWarning')}
              </p>
            ) : null}
          </PanelBody>
        </Panel>
      )

    default:
      return null
  }
}

function BigStat({
  label,
  value,
  accent = false,
}: {
  label: string
  value: string
  accent?: boolean
}) {
  return (
    <div className="rounded-lg border border-border bg-surface-2/40 px-4 py-3.5">
      <dt className="text-[10px] uppercase tracking-wide text-text-faint">{label}</dt>
      <dd className={cn('tnum mt-1.5 text-xl font-semibold', accent ? 'text-brand' : 'text-text')}>
        {value}
      </dd>
    </div>
  )
}
