// 04 · The Voice

function TabVoice() {
  const [selected, setSelected] = React.useState('colgan');
  const [hoveredUtterance, setHoveredUtterance] = React.useState(null);
  const transcripts = window.syntheticCVR || {};

  const transcript = transcripts[selected];
  if (!transcript) {
    return (
      <div style={{ padding: '32px 56px 80px' }}>
        <Eyebrow id="04 · THE VOICE" title="The conversation is the failure mode." right="NTSB PUBLIC DOCKET · CVR TRANSCRIPTS" />
        <div className="mono" style={{ color: 'var(--ink-dim)', padding: 40 }}>Loading transcript data...</div>
      </div>
    );
  }

  const utterances = transcript.utterances || [];
  const info = transcript.info || {};
  const stats = transcript.stats || {};
  const ntsb_quote = transcript.ntsb_probable_cause || '';

  // Timeline geometry
  const W = 1140, H = 240, padL = 110, padR = 24, padT = 16, padB = 32;
  const innerW = W - padL - padR;
  const laneH = 40, laneGap = 6;
  const lanes = ['CAPTAIN', 'FIRST OFFICER', 'ATC', 'WARNING SYSTEMS'];
  const laneColors = {
    'CAPTAIN': 'var(--amber)',
    'FIRST OFFICER': 'var(--blue)',
    'ATC': 'var(--steel)',
    'WARNING SYSTEMS': 'var(--red)',
  };

  // Time scale
  const maxTime = Math.max(...utterances.map(u => (u.time_offset_s || 0) + (u.duration_s || 1)), 1);
  const xs = (t) => padL + (t / maxTime) * innerW;
  const barW = (dur) => Math.max(2, (dur / maxTime) * innerW);

  // Time axis ticks
  const timeTicks = [];
  const tickStep = maxTime > 600 ? 120 : maxTime > 300 ? 60 : 30;
  for (let t = 0; t <= maxTime; t += tickStep) timeTicks.push(t);

  const formatTime = (s) => {
    const m = Math.floor(s / 60);
    const sec = Math.floor(s % 60);
    return `${m}:${sec.toString().padStart(2, '0')}`;
  };

  return (
    <div style={{ padding: '32px 56px 80px' }}>
      <Eyebrow id="04 · THE VOICE" title="The conversation is the failure mode." right="NTSB PUBLIC DOCKET · CVR TRANSCRIPTS" />

      {/* Transcript selector */}
      <div style={{ display: 'flex', gap: 1, marginBottom: 32 }}>
        {[
          { key: 'colgan', label: 'Colgan Air 3407' },
          { key: 'airflorida', label: 'Air Florida 90' },
        ].map(opt => (
          <button key={opt.key} onClick={() => { setSelected(opt.key); setHoveredUtterance(null); }}
            className="mono"
            style={{
              background: selected === opt.key ? 'var(--bg-2)' : 'transparent',
              color: selected === opt.key ? 'var(--ink)' : 'var(--ink-dimmer)',
              border: `1px solid ${selected === opt.key ? 'var(--gold)' : 'var(--line)'}`,
              padding: '10px 24px', fontSize: 11, letterSpacing: 0.2, textTransform: 'uppercase',
              cursor: 'pointer', fontWeight: selected === opt.key ? 700 : 400,
              transition: 'all 0.15s ease',
            }}>
            {opt.label}
          </button>
        ))}
      </div>

      {/* Flight info header */}
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 1,
        background: 'var(--line)', border: '1px solid var(--line)', marginBottom: 24,
      }}>
        {[
          { label: 'Flight', value: info.flight || '—' },
          { label: 'Date', value: info.date || '—' },
          { label: 'Aircraft', value: info.aircraft || '—' },
          { label: 'Fatalities / Survivors', value: `${info.fatalities ?? '—'} / ${info.survivors ?? '—'}`, accent: 'var(--red)' },
        ].map((item, i) => (
          <div key={i} style={{ background: 'var(--bg-2)', padding: '14px 16px' }}>
            <div className="mono" style={{ color: 'var(--ink-dimmer)', fontSize: 9.5, letterSpacing: 0.18, textTransform: 'uppercase' }}>
              {item.label}
            </div>
            <div className="mono" style={{ color: item.accent || 'var(--ink)', fontSize: 16, fontWeight: 700, marginTop: 4 }}>
              {item.value}
            </div>
          </div>
        ))}
      </div>

      {/* THE TIMELINE */}
      <div style={{ border: '1px solid var(--line)', background: 'rgba(20,20,20,0.6)', position: 'relative' }}>
        <div style={{ padding: '16px 24px 4px' }}>
          <div className="serif" style={{ fontSize: 17, color: 'var(--ink)' }}>CVR Timeline — Speaker Lanes</div>
          <div className="mono" style={{ color: 'var(--ink-dim)', fontSize: 11, marginTop: 4 }}>
            Each bar is a spoken utterance. The silence between bars is where the accident lives.
          </div>
        </div>

        <svg viewBox={`0 0 ${W} ${H}`} style={{ display: 'block', width: '100%', height: 'auto' }}>
          {/* Lane backgrounds and labels */}
          {lanes.map((lane, li) => {
            const ly = padT + li * (laneH + laneGap);
            return (
              <g key={lane}>
                {/* Lane background stripe */}
                <rect x={padL} y={ly} width={innerW} height={laneH}
                      fill={laneColors[lane]} opacity="0.04" />
                {/* Lane border */}
                <line x1={padL} x2={W - padR} y1={ly + laneH} y2={ly + laneH}
                      stroke="var(--line)" strokeWidth="0.5" />
                {/* Lane label */}
                <text x={padL - 8} y={ly + laneH / 2 + 3} textAnchor="end"
                      fill={laneColors[lane]} fontSize="9" fontFamily="Space Mono" opacity="0.8">
                  {lane}
                </text>
              </g>
            );
          })}

          {/* Utterance bars */}
          {utterances.map((u, i) => {
            const laneIndex = lanes.indexOf(u.speaker_role);
            if (laneIndex === -1) return null;
            const ly = padT + laneIndex * (laneH + laneGap);
            const bx = xs(u.time_offset_s || 0);
            const bw = barW(u.duration_s || 1);
            const isHovered = hoveredUtterance === i;
            return (
              <rect key={i} x={bx} y={ly + 4} width={bw} height={laneH - 8}
                    fill={laneColors[u.speaker_role]} opacity={isHovered ? 1 : 0.8}
                    stroke={isHovered ? 'var(--ink)' : 'none'} strokeWidth={isHovered ? 1.5 : 0}
                    rx="1"
                    style={{ cursor: 'pointer' }}
                    onMouseEnter={() => setHoveredUtterance(i)}
                    onMouseLeave={() => setHoveredUtterance(null)} />
            );
          })}

          {/* Time axis */}
          {timeTicks.map(t => (
            <g key={`t${t}`}>
              <line x1={xs(t)} x2={xs(t)}
                    y1={padT + lanes.length * (laneH + laneGap)} y2={padT + lanes.length * (laneH + laneGap) + 4}
                    stroke="var(--ink-dimmer)" strokeWidth="0.6" />
              <text x={xs(t)} y={padT + lanes.length * (laneH + laneGap) + 16}
                    textAnchor="middle" fill="var(--ink-dimmer)" fontSize="9" fontFamily="Space Mono">
                {formatTime(t)}
              </text>
            </g>
          ))}
        </svg>

        {/* Utterance readout panel */}
        <div style={{
          minHeight: 56, padding: '10px 24px', borderTop: '1px solid var(--line)',
          background: 'rgba(10,10,10,0.5)',
        }}>
          {hoveredUtterance != null && utterances[hoveredUtterance] ? (
            <div style={{ display: 'flex', gap: 16, alignItems: 'baseline' }}>
              <span className="mono" style={{
                color: laneColors[utterances[hoveredUtterance].speaker_role] || 'var(--ink)',
                fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.2, flexShrink: 0,
              }}>
                {utterances[hoveredUtterance].speaker || utterances[hoveredUtterance].speaker_role}
              </span>
              <span className="mono" style={{ color: 'var(--ink-dimmer)', fontSize: 10, flexShrink: 0 }}>
                {formatTime(utterances[hoveredUtterance].time_offset_s || 0)}
              </span>
              <span className="serif" style={{ color: 'var(--ink)', fontSize: 14, lineHeight: 1.4, fontStyle: 'italic' }}>
                "{utterances[hoveredUtterance].text}"
              </span>
            </div>
          ) : (
            <div className="mono" style={{ color: 'var(--ink-dimmer)', fontSize: 10 }}>
              Hover an utterance bar to read the transcript.
            </div>
          )}
        </div>
      </div>

      {/* Speaker stats panel */}
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 1,
        background: 'var(--line)', border: '1px solid var(--line)', marginTop: 24,
      }}>
        {[
          { label: 'Captain Share', value: `${stats.captain_share != null ? stats.captain_share : '—'}%`, accent: 'var(--amber)' },
          { label: 'FO Concerns Raised', value: `${stats.fo_concerns ?? '—'}`, accent: 'var(--blue)' },
          { label: 'Captain Responses', value: `${stats.captain_responses ?? '0'}`, accent: 'var(--red)' },
          { label: 'Total CVR Duration', value: stats.total_duration || '—', accent: 'var(--ink)' },
        ].map((s, i) => (
          <div key={i} style={{ background: 'var(--bg-2)', padding: '16px 18px' }}>
            <div className="mono" style={{ color: 'var(--ink-dimmer)', fontSize: 9.5, letterSpacing: 0.18, textTransform: 'uppercase' }}>
              {s.label}
            </div>
            <div className="mono" style={{ color: s.accent, fontSize: 26, fontWeight: 700, lineHeight: 1, marginTop: 6 }}>
              {s.value}
            </div>
          </div>
        ))}
      </div>

      {/* NTSB Probable cause quote */}
      {ntsb_quote && (
        <div style={{
          border: '1px solid var(--line)', background: 'rgba(20,20,20,0.6)',
          padding: '20px 24px', marginTop: 24,
        }}>
          <div className="mono" style={{ color: 'var(--red)', fontSize: 10, letterSpacing: 0.2, textTransform: 'uppercase', marginBottom: 10 }}>
            NTSB · PROBABLE CAUSE
          </div>
          <div className="serif" style={{ color: 'var(--ink)', fontSize: 15, lineHeight: 1.5, fontStyle: 'italic', textWrap: 'pretty' }}>
            "{ntsb_quote}"
          </div>
        </div>
      )}

      {/* Narrative: what the two transcripts prove together */}
      <div style={{
        border: '1px solid rgba(201,168,76,0.27)', background: 'rgba(201,168,76,0.04)',
        padding: '28px 28px 24px', marginTop: 40,
      }}>
        <div className="mono" style={{ color: 'var(--gold)', fontSize: 10, letterSpacing: 0.2, textTransform: 'uppercase' }}>
          — THE FINDING —
        </div>
        <div className="serif" style={{
          fontSize: 20, lineHeight: 1.4, color: 'var(--ink)', marginTop: 14, letterSpacing: -0.1, fontWeight: 300,
          textWrap: 'pretty',
        }}>
          Both transcripts expose the same failure: the authority gradient. In Air Florida 90 (1982), the first officer noticed ice on the wings and hinted at danger four times. The captain dismissed every one. All 74 passengers died. In Colgan 3407 (2009), the first officer never challenged the captain's stick-back response to the stick shaker. All 49 aboard died.
        </div>
        <div className="serif" style={{
          fontSize: 17, lineHeight: 1.45, color: 'var(--ink-dim)', marginTop: 16,
          textWrap: 'pretty',
        }}>
          Between those two crashes, the industry invented Crew Resource Management — the idea that the first officer is not a passenger but a co-equal voice in the cockpit. CRM was the solution to Air Florida. But Colgan proved that a rule on paper is not the same as a culture in the cockpit. The conversation is always the failure mode.
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { TabVoice });
