// WAR ROOM — Strategic Analysis sub-platforms (SWOT · Five Forces · PESTLE)
// Three classic strategy frameworks adapted to a LEGAL matter. All state is
// per-matter and persisted to localStorage so analysts can iterate across
// sessions without a backend.
//
// Exports:
//   window.WarStrategicAnalysisHub    — hub with three sub-tabs
//   window.WarSwot, WarFiveForces, WarPestle — individual panels
//
// Conventions
//   - Dark theme (W / wr tokens)
//   - Each panel is self-contained and mountable anywhere
//   - Items have { id, text, impact (1-5), confidence (1-5), owner? }
//   - All mutations route through one `useMatterStrategy` hook per matter

(function () {
  const { useState, useMemo, useCallback, useEffect } = React;
  const T = window.ArbiterTokens;
  const W = window.W;
  const wr = window.wr;
  const A = window.Arbiter || {};

  // ── Persistence ──────────────────────────────────────────────────────────
  const LS_KEY = (matterId, slice) => `arbiter:war-strategy:${matterId}:${slice}`;
  const loadLS = (matterId, slice, fallback) => {
    try { const raw = localStorage.getItem(LS_KEY(matterId, slice)); return raw ? JSON.parse(raw) : fallback; }
    catch { return fallback; }
  };
  const saveLS = (matterId, slice, value) => {
    try { localStorage.setItem(LS_KEY(matterId, slice), JSON.stringify(value)); } catch {}
  };
  const uid = (p = '') => `${p}${Math.random().toString(36).slice(2, 8)}`;

  // ── Seeds (per matter, with universal fallback) ──────────────────────────
  const SWOT_SEED = (matter) => ({
    strengths: [
      { id: uid('s'), text: 'Strong documentary record — primary source emails preserved', impact: 5, confidence: 4, owner: 'M. Kirkland' },
      { id: uid('s'), text: 'Favorable binding precedent in this circuit', impact: 5, confidence: 5, owner: 'S. Chen' },
      { id: uid('s'), text: 'Expert witness with two prior Daubert survivals', impact: 4, confidence: 4, owner: 'R. Torres' },
      { id: uid('s'), text: 'Client narrative is coherent and consistent across depositions', impact: 4, confidence: 4, owner: 'M. Kirkland' },
    ],
    weaknesses: [
      { id: uid('w'), text: 'Key fact witness has credibility issues on cross', impact: 4, confidence: 3, owner: 'J. Park' },
      { id: uid('w'), text: 'Privileged document inadvertently produced — clawback pending', impact: 3, confidence: 4, owner: 'L. Torres' },
      { id: uid('w'), text: 'Discovery budget 68% consumed before depositions', impact: 3, confidence: 5, owner: 'Finance' },
    ],
    opportunities: [
      { id: uid('o'), text: 'Opposing counsel understaffed post-departure of lead associate', impact: 4, confidence: 3, owner: 'M. Kirkland' },
      { id: uid('o'), text: 'Recent appellate ruling narrows their best theory', impact: 5, confidence: 4, owner: 'S. Chen' },
      { id: uid('o'), text: 'Judge prefers ADR — mediation window after summary judgment', impact: 3, confidence: 4, owner: 'M. Kirkland' },
    ],
    threats: [
      { id: uid('t'), text: 'Adverse third-party witness subpoenaed by opposing counsel', impact: 4, confidence: 4, owner: 'R. Torres' },
      { id: uid('t'), text: 'Parallel regulatory inquiry may produce preclusive findings', impact: 5, confidence: 3, owner: 'GC' },
      { id: uid('t'), text: 'Media attention could taint jury pool in venue', impact: 3, confidence: 2, owner: 'Comms' },
    ],
  });

  const FIVE_FORCES_SEED = () => ({
    adversary:    { score: 4, label: 'Adversary power',                drivers: [
      { id: uid('d'), text: 'Opposing counsel is AmLaw 50 with deep trial bench', impact: 5 },
      { id: uid('d'), text: 'Adversary has 2× our case budget',                 impact: 4 },
      { id: uid('d'), text: 'Key fact witness is sympathetic to them',          impact: 3 },
    ]},
    forum:        { score: 3, label: 'Forum / judicial power',         drivers: [
      { id: uid('d'), text: 'Judge has granted 82% of defense MSJs in past 3 yrs',  impact: 4 },
      { id: uid('d'), text: 'Venue jury pool leans business-friendly',             impact: 3 },
      { id: uid('d'), text: 'Local rules require pre-motion conference',           impact: 2 },
    ]},
    alternatives: { score: 3, label: 'Resolution alternatives',        drivers: [
      { id: uid('d'), text: 'ADR clause in contract — binding arbitration option', impact: 4 },
      { id: uid('d'), text: 'Early-neutral-eval available after first production', impact: 3 },
      { id: uid('d'), text: 'Client signaled willingness to settle at >$6M',       impact: 3 },
    ]},
    intervention: { score: 2, label: 'Stakeholder / intervention',     drivers: [
      { id: uid('d'), text: 'Industry amici may file on opposing side',            impact: 3 },
      { id: uid('d'), text: 'Regulatory disclosure obligations if verdict lands',  impact: 3 },
      { id: uid('d'), text: 'Class action plaintiffs monitoring outcome',          impact: 2 },
    ]},
    coalition:    { score: 4, label: 'Coalition / co-counsel',         drivers: [
      { id: uid('d'), text: 'Co-defendant shares 70% of discovery workload',       impact: 4 },
      { id: uid('d'), text: 'Joint defense privilege holding up',                  impact: 4 },
      { id: uid('d'), text: 'Local counsel has strong judicial relationships',     impact: 4 },
    ]},
  });

  const PESTLE_SEED = () => ([
    { key: 'political',     label: 'Political',     score: 3, horizon: 'mid',  drivers: [
      { id: uid('p'), text: 'DOJ priorities shifting toward this enforcement area', impact: 4 },
      { id: uid('p'), text: 'Election cycle may delay rulemaking 9–12 months',      impact: 2 },
    ]},
    { key: 'economic',      label: 'Economic',      score: 4, horizon: 'near', drivers: [
      { id: uid('p'), text: 'Damages model sensitive to Fed rate path',             impact: 4 },
      { id: uid('p'), text: 'Client facing budget freeze next quarter',             impact: 4 },
      { id: uid('p'), text: 'Insurance carrier reservation of rights issued',       impact: 3 },
    ]},
    { key: 'social',        label: 'Social',        score: 2, horizon: 'near', drivers: [
      { id: uid('p'), text: 'Public sentiment neutral — no reputational pressure',  impact: 2 },
      { id: uid('p'), text: 'Jury pool survey: 12% adverse familiarity with facts', impact: 3 },
    ]},
    { key: 'technological', label: 'Technological', score: 3, horizon: 'mid',  drivers: [
      { id: uid('p'), text: 'TAR review cleared 900k docs — 23% cost reduction',    impact: 4 },
      { id: uid('p'), text: 'Opposing side using AI summarization; opens FRE challenges', impact: 3 },
      { id: uid('p'), text: 'Cloud evidence chain certified to FRE 901(b)(9)',      impact: 3 },
    ]},
    { key: 'legal',         label: 'Legal',         score: 4, horizon: 'near', drivers: [
      { id: uid('p'), text: 'Recent circuit split on core theory — cert watch active', impact: 5 },
      { id: uid('p'), text: 'FRCP 26 proposed amendments would tighten proportionality', impact: 3 },
      { id: uid('p'), text: 'State UDTPA ruling narrows damages ceiling',           impact: 3 },
    ]},
    { key: 'environmental', label: 'Environmental', score: 2, horizon: 'far',  drivers: [
      { id: uid('p'), text: 'ESG disclosure rules may compel unfavorable admissions', impact: 3 },
      { id: uid('p'), text: 'Climate-related regulatory overlay for client industry', impact: 2 },
    ]},
  ]);

  // ── useMatterStrategy — the one source of truth ──────────────────────────
  function useMatterStrategy(matterId) {
    const [swot, setSwot] = useState(() => loadLS(matterId, 'swot', SWOT_SEED()));
    const [forces, setForces] = useState(() => loadLS(matterId, 'forces', FIVE_FORCES_SEED()));
    const [pestle, setPestle] = useState(() => loadLS(matterId, 'pestle', PESTLE_SEED()));

    useEffect(() => saveLS(matterId, 'swot',   swot),   [matterId, swot]);
    useEffect(() => saveLS(matterId, 'forces', forces), [matterId, forces]);
    useEffect(() => saveLS(matterId, 'pestle', pestle), [matterId, pestle]);

    const reset = useCallback(() => {
      setSwot(SWOT_SEED()); setForces(FIVE_FORCES_SEED()); setPestle(PESTLE_SEED());
      A.toast?.({ title: 'Strategic analysis reset', kind: 'pending' });
    }, []);

    return { swot, setSwot, forces, setForces, pestle, setPestle, reset };
  }

  // ── Small shared primitives ──────────────────────────────────────────────
  const sectionCardStyle = {
    background: W.bg.card, border: `1px solid ${W.border.subtle}`, borderRadius: 8,
    display: 'flex', flexDirection: 'column', overflow: 'hidden',
  };

  function Rating({ value, max = 5, color, onChange, readOnly }) {
    return (
      <div role="group" aria-label={`Rating: ${value} of ${max}`}
        style={{ display: 'inline-flex', gap: 3, padding: '2px 4px', borderRadius: 4,
          background: 'rgba(255,255,255,0.03)' }}>
        {Array.from({ length: max }, (_, i) => {
          const filled = i < value;
          return (
            <button key={i}
              type="button"
              aria-label={`Rate ${i + 1} of ${max}`}
              disabled={readOnly}
              onClick={() => !readOnly && onChange?.(i + 1)}
              style={{
                width: 9, height: 9, borderRadius: 2,
                background: filled ? color : 'rgba(255,255,255,0.12)',
                boxShadow: filled ? `0 0 0 1px ${color}55, 0 0 6px ${color}44` : 'none',
                border: 'none', cursor: readOnly ? 'default' : 'pointer', padding: 0,
                transition: 'background 140ms var(--easing-standard,ease), box-shadow 140ms',
              }} />
          );
        })}
      </div>
    );
  }

  function Kpi({ label, value, color, hint }) {
    return (
      <div style={{
        ...wr.stat,
        background: W.bg.tertiary,
        border: `1px solid ${W.border.subtle}`,
        padding: '12px 14px',
        transition: 'border-color 160ms, transform 160ms',
      }}>
        <span style={{ ...wr.statLabel, fontSize: 9.5, letterSpacing: '0.1em' }}>{label}</span>
        <span className="arb-num" style={{
          ...wr.statValue, color: color || W.text.primary,
          fontSize: 22, letterSpacing: '-0.02em', lineHeight: 1.05,
        }}>{value}</span>
        {hint && <span style={{ fontSize: 10, color: W.text.tertiary, letterSpacing: '0.01em' }}>{hint}</span>}
      </div>
    );
  }

  const IconBtn = ({ label, onClick, danger, children }) => (
    <button onClick={onClick} aria-label={label} title={label}
      style={{
        padding: '4px 8px', borderRadius: 5, border: `1px solid ${danger ? W.red.base + '55' : W.border.medium}`,
        background: danger ? W.red.bg : 'transparent',
        color: danger ? W.red.text : W.text.secondary,
        fontSize: 10, cursor: 'pointer', fontFamily: T.font.family,
      }}>{children || label}</button>
  );

  // ════════════════════════════════════════════════════════════════════════
  //  1. SWOT (Legal)
  // ════════════════════════════════════════════════════════════════════════
  const QUADRANTS = [
    { key: 'strengths',     label: 'Strengths',     tone: 'green',  nature: 'Internal',  valence: 'positive' },
    { key: 'weaknesses',    label: 'Weaknesses',    tone: 'amber',  nature: 'Internal',  valence: 'negative' },
    { key: 'opportunities', label: 'Opportunities', tone: 'blue',   nature: 'External',  valence: 'positive' },
    { key: 'threats',       label: 'Threats',       tone: 'red',    nature: 'External',  valence: 'negative' },
  ];

  function SwotQuadrant({ q, items, onAdd, onPatch, onRemove }) {
    const color = W[q.tone];
    const [draft, setDraft] = useState('');
    const submit = () => { if (!draft.trim()) return; onAdd(draft.trim()); setDraft(''); };
    return (
      <div style={{
        ...sectionCardStyle,
        borderTop: `3px solid ${color.base}`,
        minHeight: 260,
      }}>
        <div style={{
          ...wr.cardH,
          color: color.text, background: color.bg,
        }}>
          <span>
            {q.label}
            <span style={{ marginLeft: 8, fontSize: 9, color: W.text.tertiary, fontWeight: 400, textTransform: 'none', letterSpacing: 0 }}>
              {q.nature} · {q.valence}
            </span>
          </span>
          <span style={{ fontFamily: T.font.mono, fontSize: 11, color: color.text }}>{items.length}</span>
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: 4 }}>
          {items.length === 0 && (
            <div role="status" style={{
              padding: 24, textAlign: 'center', fontSize: 11, color: W.text.tertiary, fontStyle: 'italic',
            }}>No items yet — add the first {q.label.toLowerCase().slice(0, -1)}.</div>
          )}
          {items.map(it => (
            <div key={it.id} style={{
              padding: '8px 10px', borderBottom: `1px solid ${W.border.subtle}`,
              display: 'grid', gridTemplateColumns: '1fr auto', gap: 6, alignItems: 'start',
            }}>
              <div>
                <div style={{ fontSize: 12, color: W.text.primary, lineHeight: 1.4 }}>{it.text}</div>
                <div style={{ display: 'flex', gap: 10, alignItems: 'center', marginTop: 4, fontSize: 10, color: W.text.tertiary }}>
                  <span>impact</span>
                  <Rating value={it.impact} color={color.base} onChange={v => onPatch(it.id, { impact: v })} />
                  <span style={{ marginLeft: 6 }}>conf</span>
                  <Rating value={it.confidence} color={W.blue.base} onChange={v => onPatch(it.id, { confidence: v })} />
                  {it.owner && <span style={{ marginLeft: 'auto', fontFamily: T.font.mono, color: W.text.secondary }}>{it.owner}</span>}
                </div>
              </div>
              <IconBtn label="Remove" onClick={() => onRemove(it.id)} danger>×</IconBtn>
            </div>
          ))}
        </div>
        <div style={{ display: 'flex', gap: 6, padding: 8, borderTop: `1px solid ${W.border.subtle}`, background: W.bg.secondary }}>
          <input value={draft} onChange={e => setDraft(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter') submit(); }}
            placeholder={`Add ${q.label.toLowerCase().slice(0, -1)}…`}
            style={{
              flex: 1, minWidth: 0, height: 26,
              background: W.bg.tertiary, color: W.text.primary,
              border: `1px solid ${W.border.medium}`, borderRadius: 5,
              padding: '0 10px', fontSize: 11.5, fontFamily: T.font.family, outline: 'none',
              transition: 'border-color 140ms, box-shadow 140ms',
            }}
            onFocus={e => { e.currentTarget.style.borderColor = W.blue.base; e.currentTarget.style.boxShadow = `0 0 0 3px ${W.blue.base}33`; }}
            onBlur={e => { e.currentTarget.style.borderColor = W.border.medium; e.currentTarget.style.boxShadow = 'none'; }}
            />
          <IconBtn label="Add" onClick={submit}>Add</IconBtn>
        </div>
      </div>
    );
  }

  function WarSwot({ matterId }) {
    const { swot, setSwot } = useMatterStrategy(matterId);
    A.useTrack?.('war.swot.view', { matterId }, [matterId]);

    const addItem = (key) => (text) =>
      setSwot(s => ({ ...s, [key]: [...s[key], { id: uid(key[0]), text, impact: 3, confidence: 3, owner: 'M. Kirkland' }] }));
    const patchItem = (key) => (id, patch) =>
      setSwot(s => ({ ...s, [key]: s[key].map(x => x.id === id ? { ...x, ...patch } : x) }));
    const removeItem = (key) => (id) =>
      setSwot(s => ({ ...s, [key]: s[key].filter(x => x.id !== id) }));

    // Metrics
    const totals = QUADRANTS.map(q => swot[q.key].length);
    const totalItems = totals.reduce((a, b) => a + b, 0);
    const weightedPos = swot.strengths.reduce((a, x) => a + x.impact, 0) + swot.opportunities.reduce((a, x) => a + x.impact, 0);
    const weightedNeg = swot.weaknesses.reduce((a, x) => a + x.impact, 0) + swot.threats.reduce((a, x) => a + x.impact, 0);
    const balance = weightedPos - weightedNeg;

    return (
      <div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 10, marginBottom: 14 }}>
          <Kpi label="Total items"       value={totalItems} />
          <Kpi label="Strength points"   value={`+${weightedPos}`} color={W.green.text} hint="sum of S+O impact" />
          <Kpi label="Risk points"       value={`-${weightedNeg}`} color={W.red.text} hint="sum of W+T impact" />
          <Kpi label="Net position"      value={balance >= 0 ? `+${balance}` : balance}
            color={balance >= 0 ? W.green.text : W.red.text}
            hint="offensive ↔ defensive" />
          <Kpi label="Quadrant balance" value={totals.join(' · ')} hint="S · W · O · T" />
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          {QUADRANTS.map(q => (
            <SwotQuadrant key={q.key} q={q}
              items={swot[q.key]}
              onAdd={addItem(q.key)}
              onPatch={patchItem(q.key)}
              onRemove={removeItem(q.key)} />
          ))}
        </div>
      </div>
    );
  }

  // ════════════════════════════════════════════════════════════════════════
  //  2. Five Forces (Legal adaptation)
  // ════════════════════════════════════════════════════════════════════════
  const FORCE_ORDER = ['adversary', 'forum', 'alternatives', 'intervention', 'coalition'];
  const FORCE_COLORS = {
    adversary: W.red, forum: W.purple, alternatives: W.blue,
    intervention: W.amber, coalition: W.green,
  };

  function ForcesRadar({ forces, radius = 150 }) {
    const cx = 180, cy = 170;
    const n = FORCE_ORDER.length;
    const angle = (i) => (Math.PI * 2 * i) / n - Math.PI / 2;
    const point = (i, r) => ({ x: cx + Math.cos(angle(i)) * r, y: cy + Math.sin(angle(i)) * r });
    const gridRings = [1, 2, 3, 4, 5];
    const poly = FORCE_ORDER.map((k, i) => {
      const p = point(i, (forces[k].score / 5) * radius);
      return `${p.x},${p.y}`;
    }).join(' ');

    const avg = FORCE_ORDER.reduce((a, k) => a + forces[k].score, 0) / FORCE_ORDER.length;
    return (
      <svg width="360" height="340" viewBox="0 0 360 340" aria-label="Five Forces radar">
        <defs>
          <radialGradient id="arb-radar-glow" cx="50%" cy="50%" r="50%">
            <stop offset="0%"  stopColor={W.red.base} stopOpacity="0.28" />
            <stop offset="100%" stopColor={W.red.base} stopOpacity="0" />
          </radialGradient>
          <filter id="arb-radar-soft" x="-20%" y="-20%" width="140%" height="140%">
            <feGaussianBlur stdDeviation="1.2" />
          </filter>
        </defs>
        {/* Grid rings + axis labels */}
        {gridRings.map(r => (
          <polygon key={r}
            points={FORCE_ORDER.map((_, i) => { const p = point(i, (r / 5) * radius); return `${p.x},${p.y}`; }).join(' ')}
            fill="none" stroke={W.border.subtle} strokeWidth={r === 5 ? 1 : 0.5} strokeDasharray={r === 5 ? '0' : '2 3'} />
        ))}
        {/* Spokes */}
        {FORCE_ORDER.map((_, i) => {
          const p = point(i, radius);
          return <line key={i} x1={cx} y1={cy} x2={p.x} y2={p.y} stroke={W.border.subtle} strokeWidth="0.5" />;
        })}
        {/* Ring numerals (1 / 3 / 5) */}
        {[1, 3, 5].map(r => (
          <text key={r} x={cx + 4} y={cy - (r / 5) * radius + 2}
            fontSize="8" fill={W.text.tertiary} fontFamily={T.font.mono} opacity="0.55">{r}</text>
        ))}
        {/* Background glow */}
        <circle cx={cx} cy={cy} r={radius} fill="url(#arb-radar-glow)" />
        {/* Shape — soft fill + crisp outline */}
        <polygon points={poly} fill="rgba(239,68,68,0.12)" />
        <polygon points={poly} fill="none" stroke={W.red.base} strokeWidth="1.5"
          strokeLinejoin="round" filter="url(#arb-radar-soft)" opacity="0.5" />
        <polygon points={poly} fill="none" stroke={W.red.base} strokeWidth="1.5" strokeLinejoin="round" />
        {FORCE_ORDER.map((k, i) => {
          const p = point(i, (forces[k].score / 5) * radius);
          return (
            <g key={k}>
              <circle cx={p.x} cy={p.y} r="5" fill={FORCE_COLORS[k].base} opacity="0.2" />
              <circle cx={p.x} cy={p.y} r="3" fill={FORCE_COLORS[k].base} />
            </g>
          );
        })}
        {/* Axis labels with score */}
        {FORCE_ORDER.map((k, i) => {
          const p = point(i, radius + 18);
          const anchor = Math.cos(angle(i)) > 0.3 ? 'start' : Math.cos(angle(i)) < -0.3 ? 'end' : 'middle';
          return (
            <g key={k}>
              <text x={p.x} y={p.y - 3} textAnchor={anchor} fontSize="11"
                fill={FORCE_COLORS[k].text} fontFamily={T.font.family} fontWeight="600"
                style={{ letterSpacing: '-0.005em' }}>
                {forces[k].label}
              </text>
              <text x={p.x} y={p.y + 10} textAnchor={anchor} fontSize="9"
                fill={W.text.tertiary} fontFamily={T.font.mono}>
                {forces[k].score}/5
              </text>
            </g>
          );
        })}
        {/* Center readout */}
        <text x={cx} y={cy + 2} textAnchor="middle" fontSize="26" fontFamily={T.font.mono}
          fontWeight="700" fill={W.red.text}
          style={{ letterSpacing: '-0.02em' }}>
          {avg.toFixed(1)}
        </text>
        <text x={cx} y={cy + 20} textAnchor="middle" fontSize="9"
          fill={W.text.tertiary}
          style={{ textTransform: 'uppercase', letterSpacing: '0.14em' }}>
          PRESSURE
        </text>
      </svg>
    );
  }

  function ForceCard({ k, force, onScore, onAddDriver, onRemoveDriver, onPatchDriver }) {
    const color = FORCE_COLORS[k];
    const [draft, setDraft] = useState('');
    const submit = () => {
      if (!draft.trim()) return;
      onAddDriver({ id: uid('d'), text: draft.trim(), impact: 3 });
      setDraft('');
    };
    return (
      <div style={{ ...sectionCardStyle, borderLeft: `3px solid ${color.base}` }}>
        <div style={{ ...wr.cardH, color: color.text, background: color.bg }}>
          <span>{force.label}</span>
          <span style={{ fontFamily: T.font.mono, fontSize: 12, color: color.text }}>{force.score} / 5</span>
        </div>
        <div style={{ padding: 10 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8 }}>
            <span style={{ fontSize: 10, color: W.text.tertiary, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Pressure</span>
            <Rating value={force.score} color={color.base} onChange={onScore} />
          </div>
          {force.drivers.map(d => (
            <div key={d.id} style={{
              padding: '6px 0', borderTop: `1px solid ${W.border.subtle}`,
              display: 'grid', gridTemplateColumns: '1fr auto auto', gap: 8, alignItems: 'center',
            }}>
              <div style={{ fontSize: 11, color: W.text.primary }}>{d.text}</div>
              <Rating value={d.impact} color={color.base} onChange={v => onPatchDriver(d.id, { impact: v })} />
              <IconBtn label="Remove" onClick={() => onRemoveDriver(d.id)} danger>×</IconBtn>
            </div>
          ))}
          <div style={{ display: 'flex', gap: 6, marginTop: 8 }}>
            <input value={draft} onChange={e => setDraft(e.target.value)}
              onKeyDown={e => { if (e.key === 'Enter') submit(); }}
              placeholder="Add driver…"
              style={{
                flex: 1, height: 24, background: W.bg.tertiary, color: W.text.primary,
                border: `1px solid ${W.border.medium}`, borderRadius: 4,
                padding: '0 8px', fontSize: 11, fontFamily: T.font.family, outline: 'none',
              }} />
            <IconBtn label="Add" onClick={submit}>Add</IconBtn>
          </div>
        </div>
      </div>
    );
  }

  function WarFiveForces({ matterId }) {
    const { forces, setForces } = useMatterStrategy(matterId);
    A.useTrack?.('war.forces.view', { matterId }, [matterId]);

    const patchForce = (k, patch) => setForces(f => ({ ...f, [k]: { ...f[k], ...patch } }));
    const setScore = (k) => (v) => patchForce(k, { score: v });
    const addDriver = (k) => (d) => patchForce(k, { drivers: [...forces[k].drivers, d] });
    const removeDriver = (k) => (id) => patchForce(k, { drivers: forces[k].drivers.filter(x => x.id !== id) });
    const patchDriver = (k) => (id, patch) => patchForce(k, { drivers: forces[k].drivers.map(x => x.id === id ? { ...x, ...patch } : x) });

    const avg = FORCE_ORDER.reduce((a, k) => a + forces[k].score, 0) / FORCE_ORDER.length;
    const highest = FORCE_ORDER.map(k => ({ k, ...forces[k] })).sort((a, b) => b.score - a.score)[0];
    const lowest = FORCE_ORDER.map(k => ({ k, ...forces[k] })).sort((a, b) => a.score - b.score)[0];
    const pressure = avg >= 4 ? 'High' : avg >= 2.5 ? 'Moderate' : 'Low';
    const pressureColor = avg >= 4 ? W.red.text : avg >= 2.5 ? W.amber.text : W.green.text;

    return (
      <div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10, marginBottom: 14 }}>
          <Kpi label="Average pressure" value={avg.toFixed(1) + ' / 5'} color={pressureColor} hint={pressure} />
          <Kpi label="Strongest force"  value={highest.label}  color={FORCE_COLORS[highest.k].text} hint={`${highest.score} / 5`} />
          <Kpi label="Softest force"    value={lowest.label}   color={FORCE_COLORS[lowest.k].text}  hint={`${lowest.score} / 5`} />
          <Kpi label="Total drivers"    value={FORCE_ORDER.reduce((a, k) => a + forces[k].drivers.length, 0)} />
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '380px 1fr', gap: 14, alignItems: 'start' }}>
          <div style={{ ...sectionCardStyle, padding: 10, alignItems: 'center' }}>
            <div style={{ ...wr.cardH, width: '100%', marginBottom: 4 }}><span>Pressure radar</span></div>
            <ForcesRadar forces={forces} />
            <div style={{ fontSize: 10, color: W.text.tertiary, textAlign: 'center', marginTop: 4, maxWidth: 320 }}>
              Legal adaptation of Porter's Five Forces — each axis rated 1 (soft) to 5 (high pressure).
            </div>
          </div>
          <div style={{ display: 'grid', gap: 10 }}>
            {FORCE_ORDER.map(k => (
              <ForceCard key={k} k={k} force={forces[k]}
                onScore={setScore(k)}
                onAddDriver={addDriver(k)}
                onRemoveDriver={removeDriver(k)}
                onPatchDriver={patchDriver(k)} />
            ))}
          </div>
        </div>
      </div>
    );
  }

  // ════════════════════════════════════════════════════════════════════════
  //  3. PESTLE (Legal)
  // ════════════════════════════════════════════════════════════════════════
  const PESTLE_COLORS = {
    political: W.red, economic: W.amber, social: W.blue,
    technological: W.cyan, legal: W.purple, environmental: W.green,
  };
  const HORIZONS = ['near', 'mid', 'far'];
  const HORIZON_LABEL = { near: '< 6 mo', mid: '6–18 mo', far: '> 18 mo' };

  function PestleRow({ entry, onPatch, onAddDriver, onRemoveDriver, onPatchDriver }) {
    const color = PESTLE_COLORS[entry.key];
    const [draft, setDraft] = useState('');
    const submit = () => {
      if (!draft.trim()) return;
      onAddDriver({ id: uid('p'), text: draft.trim(), impact: 3 });
      setDraft('');
    };
    const letter = entry.label[0];
    return (
      <div style={{
        ...sectionCardStyle,
        display: 'grid',
        gridTemplateColumns: '70px 160px 1fr',
        alignItems: 'stretch',
      }}>
        <div style={{
          background: color.bg, borderRight: `1px solid ${W.border.subtle}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 38, fontFamily: T.font.mono, fontWeight: 700, color: color.text,
        }}>{letter}</div>
        <div style={{
          padding: 12, borderRight: `1px solid ${W.border.subtle}`,
          display: 'flex', flexDirection: 'column', gap: 8,
        }}>
          <div>
            <div style={{ fontSize: 13, fontWeight: 700, color: color.text, textTransform: 'uppercase', letterSpacing: '0.04em' }}>
              {entry.label}
            </div>
            <div style={{ fontSize: 10, color: W.text.tertiary, marginTop: 2 }}>{entry.drivers.length} driver{entry.drivers.length === 1 ? '' : 's'}</div>
          </div>
          <div>
            <div style={{ fontSize: 10, color: W.text.tertiary, textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 4 }}>Severity</div>
            <Rating value={entry.score} color={color.base} onChange={v => onPatch({ score: v })} />
          </div>
          <div>
            <div style={{ fontSize: 10, color: W.text.tertiary, textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 4 }}>Horizon</div>
            <div style={{ display: 'flex', gap: 4 }}>
              {HORIZONS.map(h => (
                <button key={h} onClick={() => onPatch({ horizon: h })}
                  style={{
                    padding: '3px 8px', fontSize: 10, borderRadius: 10,
                    border: `1px solid ${entry.horizon === h ? color.base : W.border.medium}`,
                    background: entry.horizon === h ? color.bg : 'transparent',
                    color: entry.horizon === h ? color.text : W.text.tertiary,
                    cursor: 'pointer', fontFamily: T.font.family,
                  }}>{HORIZON_LABEL[h]}</button>
              ))}
            </div>
          </div>
        </div>
        <div style={{ padding: 8 }}>
          {entry.drivers.map(d => (
            <div key={d.id} style={{
              display: 'grid', gridTemplateColumns: '1fr auto auto',
              gap: 8, alignItems: 'center',
              padding: '6px 4px', borderBottom: `1px solid ${W.border.subtle}`,
            }}>
              <div style={{ fontSize: 12, color: W.text.primary }}>{d.text}</div>
              <Rating value={d.impact} color={color.base} onChange={v => onPatchDriver(d.id, { impact: v })} />
              <IconBtn label="Remove" onClick={() => onRemoveDriver(d.id)} danger>×</IconBtn>
            </div>
          ))}
          <div style={{ display: 'flex', gap: 6, marginTop: 8 }}>
            <input value={draft} onChange={e => setDraft(e.target.value)}
              onKeyDown={e => { if (e.key === 'Enter') submit(); }}
              placeholder="Add driver…"
              style={{
                flex: 1, height: 24, background: W.bg.tertiary, color: W.text.primary,
                border: `1px solid ${W.border.medium}`, borderRadius: 4,
                padding: '0 8px', fontSize: 11, fontFamily: T.font.family, outline: 'none',
              }} />
            <IconBtn label="Add" onClick={submit}>Add</IconBtn>
          </div>
        </div>
      </div>
    );
  }

  function WarPestle({ matterId }) {
    const { pestle, setPestle } = useMatterStrategy(matterId);
    A.useTrack?.('war.pestle.view', { matterId }, [matterId]);

    const patchEntry = (key, patch) => setPestle(p => p.map(e => e.key === key ? { ...e, ...patch } : e));
    const addDriver = (key) => (d) => patchEntry(key, { drivers: [...pestle.find(e => e.key === key).drivers, d] });
    const removeDriver = (key) => (id) => patchEntry(key, { drivers: pestle.find(e => e.key === key).drivers.filter(x => x.id !== id) });
    const patchDriver = (key) => (id, patch) => patchEntry(key, { drivers: pestle.find(e => e.key === key).drivers.map(x => x.id === id ? { ...x, ...patch } : x) });

    const totalDrivers = pestle.reduce((a, e) => a + e.drivers.length, 0);
    const avg = pestle.reduce((a, e) => a + e.score, 0) / pestle.length;
    const near = pestle.filter(e => e.horizon === 'near');
    const highSeverity = pestle.filter(e => e.score >= 4);

    return (
      <div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10, marginBottom: 14 }}>
          <Kpi label="Categories"     value={pestle.length} />
          <Kpi label="Avg severity"   value={avg.toFixed(1) + ' / 5'} color={avg >= 3.5 ? W.red.text : avg >= 2 ? W.amber.text : W.green.text} />
          <Kpi label="Near-term hits" value={near.length} color={near.length ? W.amber.text : W.green.text} hint="< 6 months" />
          <Kpi label="High-severity"  value={highSeverity.length} color={highSeverity.length ? W.red.text : W.green.text} hint="score ≥ 4" />
        </div>
        <div style={{ display: 'grid', gap: 10 }}>
          {pestle.map(e => (
            <PestleRow key={e.key}
              entry={e}
              onPatch={(patch) => patchEntry(e.key, patch)}
              onAddDriver={addDriver(e.key)}
              onRemoveDriver={removeDriver(e.key)}
              onPatchDriver={patchDriver(e.key)} />
          ))}
        </div>
      </div>
    );
  }

  // ════════════════════════════════════════════════════════════════════════
  //  Hub wrapper with sub-nav
  // ════════════════════════════════════════════════════════════════════════
  function WarStrategicAnalysisHub({ matter }) {
    const [sub, setSub] = useState('swot');
    const matterId = matter?.id || '_default';
    const { reset } = useMatterStrategy(matterId);
    const pillStyle = (active) => ({
      padding: '8px 14px',
      fontSize: 11,
      fontWeight: active ? 700 : 500,
      color: active ? '#fff' : W.text.tertiary,
      background: active ? W.red.base : 'transparent',
      border: `1px solid ${active ? W.red.base : W.border.medium}`,
      borderRadius: 6,
      cursor: 'pointer',
      letterSpacing: '0.02em',
      whiteSpace: 'nowrap',
      fontFamily: T.font.family,
    });
    const tabs = [
      { id: 'swot',    label: 'SWOT',        hint: 'Strengths · Weaknesses · Opportunities · Threats' },
      { id: 'forces',  label: 'Five Forces', hint: 'Adversary · Forum · Alternatives · Intervention · Coalition' },
      { id: 'pestle',  label: 'PESTLE',      hint: 'Political · Economic · Social · Technological · Legal · Environmental' },
    ];
    const current = tabs.find(t => t.id === sub);
    return (
      <div>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14,
          padding: '10px 12px',
          background: W.bg.secondary, border: `1px solid ${W.border.subtle}`,
          borderRadius: 8,
        }}>
          <div style={{ display: 'flex', gap: 6 }}>
            {tabs.map(t => (
              <button key={t.id} onClick={() => setSub(t.id)} style={pillStyle(sub === t.id)}>{t.label}</button>
            ))}
          </div>
          <div style={{ fontSize: 10, color: W.text.tertiary }}>{current.hint}</div>
          <div style={{ flex: 1 }} />
          <IconBtn label="Reset to seed" onClick={() => {
            if (confirm('Reset all strategic analysis for this matter to seed defaults?')) reset();
          }}>Reset</IconBtn>
        </div>
        {sub === 'swot'   && <WarSwot matterId={matterId} />}
        {sub === 'forces' && <WarFiveForces matterId={matterId} />}
        {sub === 'pestle' && <WarPestle matterId={matterId} />}
      </div>
    );
  }

  // ── Exports ──────────────────────────────────────────────────────────────
  window.WarSwot = WarSwot;
  window.WarFiveForces = WarFiveForces;
  window.WarPestle = WarPestle;
  window.WarStrategicAnalysisHub = WarStrategicAnalysisHub;
})();
