// Data layer for The Black Box
// All synthetic datasets for aviation safety investigation.

// ------- Seeded PRNG ----------
function mulberry(a) {
  return function() {
    a |= 0; a = a + 0x6D2B79F5 | 0;
    let t = Math.imul(a ^ a >>> 15, 1 | a);
    t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
    return ((t ^ t >>> 14) >>> 0) / 4294967296;
  };
}

// ------- Format helpers ----------
function formatNumber(n) {
  if (n == null) return '—';
  return n.toLocaleString('en-US');
}

function formatRate(n) {
  if (n == null) return '—';
  if (n < 0.01) return n.toFixed(3);
  if (n < 1) return n.toFixed(2);
  return n.toFixed(1);
}

// ------- Synthetic Rates (1926–2024) ----------
const syntheticRates = (() => {
  const out = [];
  const rand = mulberry(1903); // Wright brothers

  for (let y = 1926; y <= 2024; y++) {
    const noise = () => (rand() - 0.5);

    // Commercial aviation fatal accident rate per 100k flight hours
    let commercial = null;
    if (y >= 1930) {
      if (y <= 1945) {
        // Early era: very dangerous, ~40 declining to ~25
        const t = (y - 1930) / (1945 - 1930);
        commercial = 40 - t * 15 + noise() * 6;
      } else if (y <= 1960) {
        // Post-war improvement: ~25 to ~8
        const t = (y - 1945) / (1960 - 1945);
        commercial = 25 - t * 17 + noise() * 3;
      } else if (y <= 1980) {
        // Jet age improvement: ~8 to ~2
        const t = (y - 1960) / (1980 - 1960);
        commercial = 8 - t * 6 + noise() * 1.2;
      } else if (y <= 2000) {
        // Modern era: ~2 to ~0.3
        const t = (y - 1980) / (2000 - 1980);
        commercial = 2 - t * 1.7 + noise() * 0.3;
      } else {
        // Ultra-safe: ~0.3 to ~0.07
        const t = (y - 2000) / (2024 - 2000);
        commercial = 0.3 - t * 0.23 + noise() * 0.04;
      }
      commercial = Math.max(0.01, commercial);
    }

    // General aviation rate per 100k flight hours
    let ga = null;
    if (y >= 1962) {
      if (y <= 1980) {
        const t = (y - 1962) / (1980 - 1962);
        ga = 15 - t * 5 + noise() * 1.5;
      } else if (y <= 2000) {
        const t = (y - 1980) / (2000 - 1980);
        ga = 10 - t * 4 + noise() * 0.8;
      } else {
        const t = (y - 2000) / (2024 - 2000);
        ga = 6 - t * 5 + noise() * 0.4;
      }
      ga = Math.max(0.5, ga);
    }

    out.push({
      year: y,
      commercial: commercial != null ? +commercial.toFixed(3) : null,
      ga: ga != null ? +ga.toFixed(3) : null,
    });
  }
  return out;
})();

// ------- Rate Stats ----------
const RATE_STATS = [
  { label: 'LAST FATAL US COMMERCIAL', value: '2009', sub: 'Colgan Air 3407 · Feb 12, 2009 · Clarence Center, NY' },
  { label: 'YEARS SINCE', value: '16', sub: 'Longest streak in commercial aviation history' },
  { label: 'COMMERCIAL RATE', value: '0.07', sub: 'Fatal accidents per billion passenger-miles' },
  { label: 'GA RATE', value: '~7.0', sub: 'Fatal accidents per billion passenger-miles' },
  { label: 'RATIO', value: '100x', sub: 'General aviation is ~100x more dangerous per mile' },
  { label: 'INVESTIGATIONS / YEAR', value: '~1,500', sub: 'NTSB investigations opened annually' },
];

// ------- Regulatory Events ----------
const regulatoryEvents = [
  {
    year: 1934, label: 'Bureau of Air Commerce',
    desc: 'Federal oversight of aviation safety established under the Department of Commerce. First federal accident investigation authority.',
  },
  {
    year: 1958, label: 'FAA Created',
    desc: 'Federal Aviation Act creates the FAA, consolidating civil aviation regulation. Jet age demands modern air traffic control and safety standards.',
  },
  {
    year: 1966, label: 'DOT & NTSB Established',
    desc: 'Department of Transportation Act creates the NTSB as an independent agency to investigate transportation accidents. Separation of investigation from regulation.',
  },
  {
    year: 1978, label: 'Airline Deregulation Act',
    desc: 'Economic deregulation of airlines. Routes and fares freed from CAB control. Safety regulation remains with FAA. Passenger volume surges.',
  },
  {
    year: 1988, label: 'CVR / FDR Mandate Expanded',
    desc: 'FAA mandates cockpit voice recorders and flight data recorders on all transport-category aircraft. Two-hour CVR recording requirement.',
  },
  {
    year: 1994, label: 'Commuter Safety Initiative',
    desc: 'After multiple regional airline accidents, FAA raises commuter airline standards to match Part 121 carriers. "One Level of Safety" rule.',
  },
  {
    year: 2009, label: 'Airline Safety Act',
    desc: 'After Colgan Air 3407, Congress mandates 1,500 flight hours for first officers (up from 250), fatigue management rules, and enhanced training requirements.',
  },
];

// ------- CVR Transcripts ----------
const syntheticCVR = [
  {
    flight: 'Colgan Air 3407',
    date: '2009-02-12',
    aircraft: 'Bombardier Q400',
    fatalities: 50,
    survivors: 0,
    location: 'Clarence Center, NY',
    probable_cause: "The captain's inappropriate response to the activation of the stick shaker, which led to an aerodynamic stall from which the airplane did not recover.",
    captain_speech_pct: 0.68,
    fo_warnings_ignored: 4,
    utterances: [
      { time_offset_s: 0, duration_s: 4, speaker: 'CAP', speaker_role: 'captain', text: 'Gear down. Before landing checklist.' },
      { time_offset_s: 12, duration_s: 3, speaker: 'FO', speaker_role: 'first_officer', text: 'Gear is down, three green.' },
      { time_offset_s: 22, duration_s: 5, speaker: 'FO', speaker_role: 'first_officer', text: "I'm getting some ice on the windshield here." },
      { time_offset_s: 30, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: "Yeah, it's not too bad." },
      { time_offset_s: 45, duration_s: 4, speaker: 'APP', speaker_role: 'atc', text: 'Colgan thirty-four oh seven, turn left heading three three zero.' },
      { time_offset_s: 52, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: 'Left three three zero, Colgan thirty-four oh seven.' },
      { time_offset_s: 68, duration_s: 4, speaker: 'FO', speaker_role: 'first_officer', text: "I'm seeing ice building on the leading edge. Should we cycle the deice?" },
      { time_offset_s: 76, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: "We're fine. We'll be down in a few minutes." },
      { time_offset_s: 95, duration_s: 5, speaker: 'CAP', speaker_role: 'captain', text: "I've never seen so much ice in my career. That's the most I've seen." },
      { time_offset_s: 108, duration_s: 4, speaker: 'FO', speaker_role: 'first_officer', text: "Yeah, this is... it's really accumulating. I've got it on the props too." },
      { time_offset_s: 120, duration_s: 4, speaker: 'APP', speaker_role: 'atc', text: 'Colgan thirty-four oh seven, descend and maintain two thousand three hundred.' },
      { time_offset_s: 128, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: 'Two thousand three hundred, Colgan thirty-four oh seven.' },
      { time_offset_s: 145, duration_s: 5, speaker: 'FO', speaker_role: 'first_officer', text: "Captain, this ice situation is getting worse. I think we need to request a hold or something." },
      { time_offset_s: 155, duration_s: 4, speaker: 'CAP', speaker_role: 'captain', text: "No, we're almost there. Just keep an eye on the speed." },
      { time_offset_s: 175, duration_s: 5, speaker: 'CAP', speaker_role: 'captain', text: 'Did you hear about that prior accident with the Q400? The Buffalo thing?' },
      { time_offset_s: 185, duration_s: 3, speaker: 'FO', speaker_role: 'first_officer', text: "No, what happened?" },
      { time_offset_s: 192, duration_s: 6, speaker: 'CAP', speaker_role: 'captain', text: "I don't know. Something about icing. I'm sure they'll figure it out." },
      { time_offset_s: 210, duration_s: 4, speaker: 'APP', speaker_role: 'atc', text: 'Colgan thirty-four oh seven, cleared ILS runway two three.' },
      { time_offset_s: 218, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: 'Cleared ILS two three, Colgan thirty-four oh seven.' },
      { time_offset_s: 240, duration_s: 5, speaker: 'FO', speaker_role: 'first_officer', text: "I really think we have too much ice on this airplane." },
      { time_offset_s: 250, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: "We're fine. Flaps fifteen." },
      { time_offset_s: 258, duration_s: 2, speaker: 'FO', speaker_role: 'first_officer', text: 'Flaps fifteen.' },
      { time_offset_s: 270, duration_s: 1, speaker: 'SYS', speaker_role: 'warning_system', text: '[STICK SHAKER]' },
      { time_offset_s: 272, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: '[Pulls back on control column]' },
      { time_offset_s: 275, duration_s: 2, speaker: 'FO', speaker_role: 'first_officer', text: 'Jesus Christ.' },
      { time_offset_s: 278, duration_s: 1, speaker: 'SYS', speaker_role: 'warning_system', text: '[STICK PUSHER]' },
      { time_offset_s: 280, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: '[Overrides stick pusher — pulls back again]' },
      { time_offset_s: 285, duration_s: 2, speaker: 'FO', speaker_role: 'first_officer', text: "We're—we're in a stall." },
      { time_offset_s: 290, duration_s: 1, speaker: 'SYS', speaker_role: 'warning_system', text: '[BANK ANGLE — BANK ANGLE]' },
      { time_offset_s: 295, duration_s: 3, speaker: 'FO', speaker_role: 'first_officer', text: "We're down." },
      { time_offset_s: 301, duration_s: 0, speaker: 'SYS', speaker_role: 'warning_system', text: '[END OF RECORDING]' },
    ],
  },
  {
    flight: 'Air Florida 90',
    date: '1982-01-13',
    aircraft: 'Boeing 737-222',
    fatalities: 78,
    survivors: 5,
    location: '14th Street Bridge, Washington, D.C.',
    probable_cause: "The flight crew's failure to use engine anti-ice during ground operation and takeoff, the captain's decision to take off with snow and ice on the airfoil surfaces, and the captain's failure to abort the takeoff when the engine instrument readings were abnormal.",
    captain_speech_pct: 0.55,
    fo_warnings_ignored: 5,
    utterances: [
      { time_offset_s: 0, duration_s: 4, speaker: 'FO', speaker_role: 'first_officer', text: "Look at all that ice on the wing out there. See that?" },
      { time_offset_s: 8, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: "Yeah, I see it. We've been deiced." },
      { time_offset_s: 15, duration_s: 5, speaker: 'FO', speaker_role: 'first_officer', text: "That deice job was forty-five minutes ago. I think we need another one." },
      { time_offset_s: 24, duration_s: 4, speaker: 'CAP', speaker_role: 'captain', text: "No, we're not going back. We'll lose our slot. It'll be fine." },
      { time_offset_s: 35, duration_s: 3, speaker: 'TWR', speaker_role: 'atc', text: 'Palm ninety, taxi into position and hold runway three six.' },
      { time_offset_s: 42, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: 'Position and hold, Palm ninety.' },
      { time_offset_s: 50, duration_s: 5, speaker: 'FO', speaker_role: 'first_officer', text: "Boy, this is... it's really coming down now. There's snow all over the wings." },
      { time_offset_s: 58, duration_s: 2, speaker: 'CAP', speaker_role: 'captain', text: "That's just a dusting." },
      { time_offset_s: 65, duration_s: 3, speaker: 'TWR', speaker_role: 'atc', text: 'Palm ninety, cleared for takeoff.' },
      { time_offset_s: 70, duration_s: 2, speaker: 'CAP', speaker_role: 'captain', text: 'Cleared for takeoff, Palm ninety.' },
      { time_offset_s: 75, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: "Okay, here we go. Set takeoff power." },
      { time_offset_s: 80, duration_s: 4, speaker: 'FO', speaker_role: 'first_officer', text: "The EPR readings don't look right. Look at that." },
      { time_offset_s: 88, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: "They're within limits. Keep going." },
      { time_offset_s: 95, duration_s: 5, speaker: 'FO', speaker_role: 'first_officer', text: "That doesn't seem right. EPR is reading way off from what it should be." },
      { time_offset_s: 104, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: "It's okay." },
      { time_offset_s: 110, duration_s: 2, speaker: 'FO', speaker_role: 'first_officer', text: 'V-one.' },
      { time_offset_s: 115, duration_s: 2, speaker: 'FO', speaker_role: 'first_officer', text: 'Rotate.' },
      { time_offset_s: 120, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: 'Positive rate. Gear up.' },
      { time_offset_s: 126, duration_s: 2, speaker: 'FO', speaker_role: 'first_officer', text: 'Gear up.' },
      { time_offset_s: 132, duration_s: 4, speaker: 'FO', speaker_role: 'first_officer', text: "We're not climbing. We're barely holding altitude." },
      { time_offset_s: 140, duration_s: 3, speaker: 'CAP', speaker_role: 'captain', text: "Come on. Come on." },
      { time_offset_s: 148, duration_s: 1, speaker: 'SYS', speaker_role: 'warning_system', text: '[STALL WARNING]' },
      { time_offset_s: 150, duration_s: 4, speaker: 'FO', speaker_role: 'first_officer', text: "Larry, we're going down, Larry." },
      { time_offset_s: 156, duration_s: 2, speaker: 'CAP', speaker_role: 'captain', text: 'I know it.' },
      { time_offset_s: 160, duration_s: 3, speaker: 'TWR', speaker_role: 'atc', text: 'Palm ninety, contact departure.' },
      { time_offset_s: 165, duration_s: 1, speaker: 'SYS', speaker_role: 'warning_system', text: '[STALL WARNING]' },
      { time_offset_s: 168, duration_s: 3, speaker: 'FO', speaker_role: 'first_officer', text: "Larry—" },
      { time_offset_s: 175, duration_s: 2, speaker: 'CAP', speaker_role: 'captain', text: "[Sound of impact]" },
      { time_offset_s: 180, duration_s: 0, speaker: 'SYS', speaker_role: 'warning_system', text: '[END OF RECORDING]' },
    ],
  },
];

// ------- Lessons: Key Accidents ----------
const syntheticLessons = [
  {
    flight: 'Grand Canyon Midair',
    year: 1956,
    fatalities: 128,
    aircraft: 'TWA L-1049 / UAL DC-7',
    probable_cause: 'Uncontrolled airspace over Grand Canyon allowed VFR-on-top flight plans in same corridor. No radar separation.',
    rule_change: 'Led directly to the Federal Aviation Act of 1958 and creation of the FAA. Established positive radar control of all IFR traffic.',
  },
  {
    flight: 'Eastern Air Lines 401',
    year: 1972,
    fatalities: 101,
    aircraft: 'Lockheed L-1011',
    probable_cause: 'Entire crew distracted by a burned-out landing gear indicator light. Autopilot accidentally disconnected. No one monitoring altitude.',
    rule_change: 'Pioneered Crew Resource Management (CRM). Established that captains must delegate monitoring duties. Changed cockpit culture worldwide.',
  },
  {
    flight: 'Tenerife Airport Disaster',
    year: 1977,
    fatalities: 583,
    aircraft: 'KLM 747 / Pan Am 747',
    probable_cause: 'KLM captain initiated takeoff without clearance in heavy fog. Ambiguous ATC phraseology. Pan Am still on runway.',
    rule_change: 'Standardized ATC phraseology worldwide. Eliminated ambiguous terms. Required explicit takeoff clearance. CRM training accelerated.',
  },
  {
    flight: 'Air Florida 90',
    year: 1982,
    fatalities: 78,
    aircraft: 'Boeing 737-222',
    probable_cause: "Failure to use engine anti-ice during ground operation and takeoff. Captain's decision to take off with contaminated airfoil surfaces.",
    rule_change: 'Strengthened deicing procedures. Required crew training on cold weather operations. First officer authority to challenge captain reinforced.',
  },
  {
    flight: 'United Airlines 232',
    year: 1989,
    fatalities: 112,
    aircraft: 'McDonnell Douglas DC-10',
    probable_cause: 'Uncontained engine failure severed all three hydraulic systems. Complete loss of flight controls. No redundancy for this failure mode.',
    rule_change: 'Redesigned hydraulic systems with additional redundancy. Improved engine fan disk inspection protocols. CRM success story — 184 survived.',
  },
  {
    flight: 'USAir 427',
    year: 1994,
    fatalities: 132,
    aircraft: 'Boeing 737-300',
    probable_cause: 'Rudder power control unit (PCU) malfunction caused uncommanded full rudder deflection. Known design flaw.',
    rule_change: 'Longest NTSB investigation in history (4.5 years). Led to redesign of 737 rudder PCU on entire worldwide fleet. Required dual-concentric rudder valves.',
  },
  {
    flight: 'TWA 800',
    year: 1996,
    fatalities: 230,
    aircraft: 'Boeing 747-131',
    probable_cause: 'Center wing fuel tank explosion caused by ignition of flammable fuel-air vapors. Aging wiring near tank.',
    rule_change: 'FAA mandated fuel tank inerting systems (FTIS) on all commercial aircraft. Required flammability reduction means in center wing tanks.',
  },
  {
    flight: 'Colgan Air 3407',
    year: 2009,
    fatalities: 50,
    aircraft: 'Bombardier Q400',
    probable_cause: "Captain's inappropriate response to stick shaker activation. Inadequate training. Crew fatigue.",
    rule_change: 'Airline Safety and Federal Aviation Administration Extension Act of 2010. First officer hours raised from 250 to 1,500. Fatigue management mandated.',
  },
];

// ------- Recommendation Sankey Flow ----------
const syntheticRecommendations = {
  total: 15000,
  adopted: 9800,
  open: 3200,
  superseded: 1500,
  rejected: 500,
};

// ------- META: Headline Stats ----------
const META = {
  headline: 'The Black Box',
  subtitle: 'How aviation safety was written in blood',
  span: '1926–2024',
  source: 'NTSB',
  total_investigations: '~92,000',
  total_recommendations: '~15,000',
  adoption_rate: '~82%',
};

// ------- Expose to window ----------
Object.assign(window, {
  mulberry, formatNumber, formatRate,
  syntheticRates, RATE_STATS,
  regulatoryEvents, syntheticCVR,
  syntheticLessons, syntheticRecommendations,
  META,
});
