// ============================================================
// bedside/neonatal.js
// NEONATAL ASSESSMENT (Fenton growth) + NRP pathway + Apgar.
// ============================================================

import { S } from './shared.js';

// Fenton 2013 LMS data (weight in grams, GA in weeks).
//
// LMS parameters derived empirically from peditools.org/fenton2013 —
// peditools is widely used and consistent with the published
// Fenton TR, Kim JH. BMC Pediatrics 2013;13:59 reference. Each week's
// triple was fit against 6 probe weights per week (RMSE < 0.005 z-score
// units). Replaces an earlier hand-rounded table whose z-scores drifted
// ~0.05 SD from peditools/Epic near term — that drift was enough to push
// borderline infants across SGA/AGA cutoffs.
//
// Validated test cases:
//   40 5/7 wk male, 3070g  → z = -1.42 (Epic: -1.43, peditools: -1.42)
var fentonLMS = {
  male: {
    22:{L:0.5885,M:496,S:0.12802},23:{L:0.7565,M:571,S:0.14547},24:{L:0.9128,M:651,S:0.16235},25:{L:1.0544,M:741,S:0.17765},
    26:{L:1.1862,M:841,S:0.19029},27:{L:1.3051,M:953,S:0.19989},28:{L:1.3699,M:1079,S:0.20777},29:{L:1.4165,M:1223,S:0.21163},
    30:{L:1.4172,M:1388,S:0.21185},31:{L:1.3755,M:1578,S:0.20785},32:{L:1.2952,M:1790,S:0.20112},33:{L:1.1974,M:2018,S:0.19143},
    34:{L:1.0743,M:2255,S:0.18119},35:{L:0.9583,M:2493,S:0.16992},36:{L:0.8460,M:2726,S:0.16001},37:{L:0.7543,M:2947,S:0.15072},
    38:{L:0.6650,M:3156,S:0.14304},39:{L:0.5881,M:3360,S:0.13641},40:{L:0.5237,M:3568,S:0.13173},41:{L:0.4691,M:3785,S:0.12863},
    42:{L:0.4216,M:4014,S:0.12735}
  },
  female: {
    22:{L:-0.0868,M:481,S:0.13605},23:{L:0.2119,M:537,S:0.14635},24:{L:0.5281,M:606,S:0.16134},25:{L:0.8258,M:694,S:0.18077},
    26:{L:1.0501,M:792,S:0.19889},27:{L:1.2084,M:899,S:0.21323},28:{L:1.2599,M:1017,S:0.22437},29:{L:1.2539,M:1152,S:0.22982},
    30:{L:1.2262,M:1306,S:0.23082},31:{L:1.1223,M:1482,S:0.22733},32:{L:1.0122,M:1681,S:0.21846},33:{L:0.8746,M:1897,S:0.20681},
    34:{L:0.7299,M:2126,S:0.19407},35:{L:0.5929,M:2362,S:0.18059},36:{L:0.4534,M:2602,S:0.17028},37:{L:0.3462,M:2835,S:0.16139},
    38:{L:0.2636,M:3050,S:0.15513},39:{L:0.2069,M:3239,S:0.15004},40:{L:0.1670,M:3415,S:0.14649},41:{L:0.1517,M:3596,S:0.14359},
    42:{L:0.1308,M:3787,S:0.14127}
  }
};

function interpolateLMS(table, val) {
  var keys = Object.keys(table).map(Number).sort(function(a,b){return a-b;});
  if (val <= keys[0]) return table[keys[0]];
  if (val >= keys[keys.length-1]) return table[keys[keys.length-1]];
  for (var i = 0; i < keys.length - 1; i++) {
    if (val >= keys[i] && val <= keys[i+1]) {
      var t = (val - keys[i]) / (keys[i+1] - keys[i]);
      var a = table[keys[i]], b = table[keys[i+1]];
      return { L: a.L + t*(b.L-a.L), M: a.M + t*(b.M-a.M), S: a.S + t*(b.S-a.S) };
    }
  }
  return table[keys[0]];
}

function calcZ(value, L, M, S) {
  if (Math.abs(L) < 0.001) return Math.log(value / M) / S;
  return (Math.pow(value / M, L) - 1) / (L * S);
}

function zToPercentile(z) {
  // Approximation of the standard normal CDF
  var a1=0.254829592, a2=-0.284496736, a3=1.421413741, a4=-1.453152027, a5=1.061405429, p=0.3275911;
  var sign = z < 0 ? -1 : 1;
  var x = Math.abs(z) / Math.sqrt(2);
  var t = 1 / (1 + p * x);
  var y = 1 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t * Math.exp(-x*x);
  return Math.round(((1 + sign * y) / 2) * 1000) / 10;
}

function classifyGA(weeks, days) {
  var total = weeks + (days || 0) / 7;
  if (total < 28) return { label: 'Extremely Preterm', color: '#dc2626', icon: 'fa-triangle-exclamation' };
  if (total < 32) return { label: 'Very Preterm', color: '#ea580c', icon: 'fa-triangle-exclamation' };
  if (total < 34) return { label: 'Moderate Preterm', color: '#d97706', icon: 'fa-circle-exclamation' };
  if (total < 37) return { label: 'Late Preterm', color: '#ca8a04', icon: 'fa-circle-info' };
  if (total < 39) return { label: 'Early Term', color: '#2563eb', icon: 'fa-circle-info' };
  if (total < 41) return { label: 'Full Term', color: '#16a34a', icon: 'fa-circle-check' };
  if (total < 42) return { label: 'Late Term', color: '#d97706', icon: 'fa-circle-info' };
  return { label: 'Post Term', color: '#dc2626', icon: 'fa-triangle-exclamation' };
}

function classifyWeight(percentile) {
  if (percentile < 3) return { label: 'Severely SGA', color: '#dc2626', detail: '<3rd percentile' };
  if (percentile < 10) return { label: 'SGA', color: '#ea580c', detail: '<10th percentile' };
  if (percentile > 97) return { label: 'Severely LGA', color: '#dc2626', detail: '>97th percentile' };
  if (percentile > 90) return { label: 'LGA', color: '#ea580c', detail: '>90th percentile' };
  return { label: 'AGA', color: '#16a34a', detail: '10th-90th percentile' };
}

function classifyBirthWeight(grams) {
  if (grams < 1000) return { label: 'Extremely Low Birth Weight (ELBW)', color: '#dc2626' };
  if (grams < 1500) return { label: 'Very Low Birth Weight (VLBW)', color: '#ea580c' };
  if (grams < 2500) return { label: 'Low Birth Weight (LBW)', color: '#d97706' };
  if (grams <= 4000) return { label: 'Normal Birth Weight', color: '#16a34a' };
  return { label: 'Macrosomia (>4000g)', color: '#ea580c' };
}

function neoAssess() {
  var weeks = parseInt(document.getElementById('neo-ga-weeks').value);
  var days = parseInt(document.getElementById('neo-ga-days').value) || 0;
  var weight = parseFloat(document.getElementById('neo-weight').value);
  var sex = document.getElementById('neo-sex').value;
  var resultDiv = document.getElementById('neo-result');

  if (!weeks || !weight) {
    resultDiv.innerHTML = '<p style="color:var(--red);font-size:13px;">Enter GA and birth weight.</p>';
    return;
  }

  var gaDecimal = weeks + days / 7;
  var gaClass = classifyGA(weeks, days);
  var bwClass = classifyBirthWeight(weight);

  // Calculate percentile using Fenton LMS
  var lms = interpolateLMS(fentonLMS[sex], gaDecimal);
  var z = calcZ(weight, lms.L, lms.M, lms.S);
  var percentile = zToPercentile(z);
  var wtClass = classifyWeight(percentile);
  var expectedWeight = Math.round(lms.M);

  var html = '';

  // GA Classification
  html += '<div style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:12px;">';
  html += '<div style="flex:1;min-width:200px;padding:14px;border-radius:10px;background:' + gaClass.color + '10;border:1.5px solid ' + gaClass.color + '30;">';
  html += '<div style="font-size:12px;color:var(--g500);margin-bottom:4px;">Gestational Age Classification</div>';
  html += '<div style="font-size:18px;font-weight:700;color:' + gaClass.color + ';"><i class="fas ' + gaClass.icon + '"></i> ' + gaClass.label + '</div>';
  html += '<div style="font-size:13px;color:var(--g600);margin-top:4px;">' + weeks + ' weeks ' + days + ' days (' + gaDecimal.toFixed(1) + ' weeks)</div>';
  html += '</div>';

  // Weight Classification (AGA/SGA/LGA)
  html += '<div style="flex:1;min-width:200px;padding:14px;border-radius:10px;background:' + wtClass.color + '10;border:1.5px solid ' + wtClass.color + '30;">';
  html += '<div style="font-size:12px;color:var(--g500);margin-bottom:4px;">Weight for Gestational Age</div>';
  html += '<div style="font-size:18px;font-weight:700;color:' + wtClass.color + ';">' + wtClass.label + '</div>';
  html += '<div style="font-size:13px;color:var(--g600);margin-top:4px;">' + percentile.toFixed(1) + 'th percentile (' + wtClass.detail + ')</div>';
  html += '</div>';
  html += '</div>';

  // Birth Weight Category
  html += '<div style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:12px;">';
  html += '<div style="flex:1;min-width:200px;padding:14px;border-radius:10px;background:' + bwClass.color + '10;border:1.5px solid ' + bwClass.color + '30;">';
  html += '<div style="font-size:12px;color:var(--g500);margin-bottom:4px;">Birth Weight Category</div>';
  html += '<div style="font-size:18px;font-weight:700;color:' + bwClass.color + ';">' + bwClass.label + '</div>';
  html += '<div style="font-size:13px;color:var(--g600);margin-top:4px;">' + weight + 'g (' + (weight/1000).toFixed(2) + ' kg)</div>';
  html += '</div>';

  // Stats
  html += '<div style="flex:1;min-width:200px;padding:14px;border-radius:10px;background:var(--g50);border:1.5px solid var(--g200);">';
  html += '<div style="font-size:12px;color:var(--g500);margin-bottom:4px;">Fenton Growth Data (' + (sex === 'male' ? 'Male' : 'Female') + ')</div>';
  html += '<div style="font-size:13px;color:var(--g700);line-height:1.8;">';
  html += '<strong>Expected weight (50th %ile):</strong> ' + expectedWeight + 'g<br>';
  html += '<strong>Z-score:</strong> ' + z.toFixed(2) + '<br>';
  html += '<strong>Percentile:</strong> ' + percentile.toFixed(1) + '%';
  html += '</div></div>';
  html += '</div>';

  // Reference
  html += '<p style="font-size:11px;color:var(--g400);margin:8px 0 0;">Fenton TR, Kim JH. A systematic review and meta-analysis to revise the Fenton growth chart for preterm infants. BMC Pediatrics 2013;13:59. GA classification per ACOG/AAP definitions.</p>';

  resultDiv.innerHTML = html;
}

// ---- NRP pathway + drug calc -----------------------------------------

function renderPathway() {
  var el = document.getElementById('nrp-pathway-static');
  if (!el || el.dataset.rendered) return;
  var html = '';
  html += S.stepBox('#3b82f6', 'BIRTH — ASSESS (first 30 sec)', 'Term? Tone? Breathing/crying? If <strong>all yes</strong> → routine care with mother. If <strong>any no</strong> → warm, dry, stimulate, position airway, clear airway PRN, evaluate HR & respirations.');
  html += S.arrow;
  html += S.stepBox('#8b5cf6', 'HR &lt; 100 OR apneic/gasping (60 sec)', '<strong>Start PPV</strong> 40-60 breaths/min, room air for term / 21-30% for preterm. Attach SpO2 (right hand) &plusmn; ECG. MR SOPA if ineffective: <em>M</em>ask adjust, <em>R</em>eposition, <em>S</em>uction, <em>O</em>pen mouth, <em>P</em>ressure increase, <em>A</em>lternative airway.');
  html += S.arrow;
  html += S.stepBox('#f59e0b', 'HR &lt; 100 after 30 sec effective PPV', 'Reassess ventilation — ensure chest rise. Consider increasing FiO2, intubation, or LMA. Continue PPV.');
  html += S.arrow;
  html += S.stepBox('#ef4444', 'HR &lt; 60 after 30 sec of effective PPV', '<strong>Intubate + Chest compressions</strong> — 3:1 ratio (90 compressions + 30 breaths per minute), FiO2 100%, lower 1/3 sternum, depth 1/3 AP chest.');
  html += S.arrow;
  html += S.stepBox('#dc2626', 'HR &lt; 60 despite compressions + PPV x 60 sec', '<strong>Epinephrine</strong> 1:10,000 (0.1 mg/mL): <br>&bull; <strong>IV/IO:</strong> 0.01-0.03 mg/kg (0.1-0.3 mL/kg) — preferred<br>&bull; <strong>ETT:</strong> 0.05-0.1 mg/kg (0.5-1 mL/kg) — while IV being placed<br>Repeat q3-5 min. If hypovolemia: <strong>NS 10 mL/kg IV/IO</strong> over 5-10 min.');
  html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:8px;margin-top:14px;">';
  html += '<div style="padding:10px;background:var(--g50);border-radius:6px;font-size:12px;"><strong>Target SpO2 (preductal):</strong><br>1 min: 60-65%<br>2 min: 65-70%<br>3 min: 70-75%<br>4 min: 75-80%<br>5 min: 80-85%<br>10 min: 85-95%</div>';
  html += '<div style="padding:10px;background:var(--g50);border-radius:6px;font-size:12px;"><strong>Initial ETT size:</strong><br>&lt;1 kg / &lt;28 wk: <strong>2.5</strong><br>1-2 kg / 28-34 wk: <strong>3.0</strong><br>2-3 kg / 34-38 wk: <strong>3.5</strong><br>&gt;3 kg / &gt;38 wk: <strong>3.5-4.0</strong></div>';
  html += '<div style="padding:10px;background:var(--g50);border-radius:6px;font-size:12px;"><strong>ETT depth (lip):</strong><br>~ 6 + weight(kg) cm</div>';
  html += '</div>';
  el.innerHTML = html;
  el.dataset.rendered = '1';
}

function calcNRP() {
  var wt = parseFloat(document.getElementById('nrp-weight').value);
  var el = document.getElementById('nrp-result');
  if (!wt) { el.innerHTML = '<p style="color:var(--red);font-size:13px;">Enter weight (kg).</p>'; return; }
  var epiIvLow = Math.round(wt * 0.01 * 100) / 100;
  var epiIvHigh = Math.round(wt * 0.03 * 100) / 100;
  var epiEtLow = Math.round(wt * 0.05 * 100) / 100;
  var epiEtHigh = Math.round(wt * 0.1 * 100) / 100;
  var ns = Math.round(wt * 10);
  var d10 = Math.round(wt * 2 * 10) / 10;
  var html = '<div style="padding:10px 14px;border-radius:8px;background:var(--red)10;border:1.5px solid var(--red);margin-bottom:10px;"><strong style="color:var(--red);">NRP doses — ' + wt + ' kg</strong></div>';
  var pk = function(txt) { return ' <span style="color:var(--g500);font-size:11px;">(' + txt + ')</span>'; };
  html += S.drugTable(
    S.drugRow('Epinephrine 1:10,000', epiIvLow + '-' + epiIvHigh + ' mg, ' + (Math.round(epiIvLow*10)/10) + '-' + (Math.round(epiIvHigh*10)/10) + ' mL' + pk('0.01-0.03 mg/kg = 0.1-0.3 mL/kg'), 'IV / IO', 'Preferred route. Repeat q3-5 min.') +
    S.drugRow('Epinephrine 1:10,000', epiEtLow + '-' + epiEtHigh + ' mg, ' + (Math.round(epiEtLow*10)/10) + '-' + (Math.round(epiEtHigh*10)/10) + ' mL' + pk('0.05-0.1 mg/kg = 0.5-1 mL/kg'), 'ETT', 'While IV being placed.') +
    S.drugRow('Normal saline', ns + ' mL' + pk('10 mL/kg'), 'IV / IO', 'Over 5-10 min for volume. Repeat PRN.') +
    S.drugRow('Dextrose 10%', d10 + ' mL' + pk('2 mL/kg = 0.2 g/kg'), 'IV slow push', 'For documented hypoglycemia. Then D10 infusion 4-6 mg/kg/min.')
  );
  html += '<div style="padding:10px;background:#fef3c7;border-radius:6px;font-size:12px;color:#92400e;"><strong>Concentration note:</strong> NRP uses epinephrine <strong>1:10,000</strong> (0.1 mg/mL). NOT 1:1000 (1 mg/mL) — that is IM for anaphylaxis / older patients.</div>';
  html += S.ref('AHA/AAP Neonatal Resuscitation Program (NRP) 8th edition, 2020.');
  el.innerHTML = html;
}

// ---- Apgar -----------------------------------------------------------

function calcApgar() {
  var keys = ['appearance','pulse','grimace','activity','respiration'];
  var total = keys.reduce(function(s, k) {
    return s + (parseInt(document.getElementById('apgar-' + k).value) || 0);
  }, 0);
  var el = document.getElementById('apgar-result');
  var color, severity, guidance;
  if (total >= 7) {
    color = '#10b981'; severity = 'Reassuring';
    guidance = 'Routine newborn care. Continue reassessment. Repeat at 5 min.';
  } else if (total >= 4) {
    color = '#f59e0b'; severity = 'Moderately depressed';
    guidance = 'Stimulate, clear airway, warm. Give O2 if cyanotic. Ventilate with PPV if HR &lt;100 or apneic/gasping. Reassess q30 sec.';
  } else {
    color = '#ef4444'; severity = 'Severely depressed';
    guidance = 'Full NRP pathway — PPV immediately. Intubate if PPV ineffective. Chest compressions if HR &lt;60. Epinephrine and volume per NRP.';
  }
  var html = '<div style="padding:10px 14px;border-radius:8px;background:' + color + '10;border:1.5px solid ' + color + ';">';
  html += '<strong style="color:' + color + ';font-size:16px;">Apgar: ' + total + '/10 — ' + severity + '</strong>';
  html += '<div style="font-size:12px;color:var(--g700);margin-top:6px;line-height:1.5;">' + guidance + '</div></div>';
  html += '<p style="font-size:11px;color:var(--g400);margin-top:8px;font-style:italic;">Apgar is a description of status — <strong>never</strong> delay resuscitation while scoring. Follow NRP algorithm based on HR and breathing. Apgar &lt;7 at 5 min: repeat q5 min up to 20 min.</p>';
  el.innerHTML = html;
}

export function init() {
  // Neonatal assessment
  document.addEventListener('click', function(e) {
    if (e.target.id === 'btn-neo-assess' || e.target.closest('#btn-neo-assess')) neoAssess();
  });

  // NRP pathway render + calc
  document.addEventListener('DOMContentLoaded', renderPathway);
  document.addEventListener('tabChanged', function() { setTimeout(renderPathway, 100); });
  if (document.readyState !== 'loading') setTimeout(renderPathway, 0);

  document.addEventListener('click', function(e) {
    if (e.target.id === 'btn-nrp-calc' || e.target.closest('#btn-nrp-calc')) calcNRP();
    // Render NRP pathway when Neonatal sub-pill is clicked (in case component loaded late)
    var np = e.target.closest && e.target.closest('[data-em="neonatal"]');
    if (np) setTimeout(renderPathway, 0);
    var nav = e.target.closest && e.target.closest('[data-calc="bedside"]');
    if (nav) setTimeout(renderPathway, 50);
  });

  // Apgar
  document.addEventListener('click', function(e) {
    if (e.target.id === 'btn-apgar-calc' || e.target.closest('#btn-apgar-calc')) calcApgar();
  });
}
