var bmiCache = null;

export function loadBmiLmsData() {
  if (bmiCache) return Promise.resolve(bmiCache);
  return fetch('/data/calculators/bmi-lms.json', { credentials: 'same-origin' })
    .then(function(response) {
      if (!response.ok) throw new Error('Failed to load BMI LMS data');
      return response.json();
    })
    .then(function(data) {
      bmiCache = data.lms || {};
      return bmiCache;
    });
}

export function interpolateLMS(lmsTable, val) {
  var keys = Object.keys(lmsTable).map(Number).sort(function(a,b){return a-b;});
  if (val <= keys[0]) return lmsTable[keys[0]];
  if (val >= keys[keys.length-1]) return lmsTable[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 = lmsTable[keys[i]], b = lmsTable[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 lmsTable[keys[0]];
}

function normalCDF(z) {
  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;
  z = Math.abs(z) / Math.sqrt(2);
  var t = 1 / (1 + p * z);
  var y = 1 - (((((a5*t+a4)*t)+a3)*t+a2)*t+a1)*t*Math.exp(-z*z);
  return 0.5 * (1 + sign * y);
}

export function calcBMIPercentile(bmi, L, M, S) {
  var z;
  if (Math.abs(L) < 0.001) z = Math.log(bmi / M) / S;
  else z = (Math.pow(bmi / M, L) - 1) / (L * S);
  var p = normalCDF(z);
  return { z: z, percentile: Math.round(p * 10000) / 100 };
}

export function valueFromLMS(L, M, S, z) {
  if (Math.abs(L) < 0.001) return M * Math.exp(S * z);
  return M * Math.pow(1 + L * S * z, 1 / L);
}

export function classifyBMI(percentile, bmi, lms) {
  var bmi95 = valueFromLMS(lms.L, lms.M, lms.S, 1.645);
  var pctOf95 = (bmi / bmi95) * 100;

  if (percentile >= 95) {
    if (pctOf95 >= 140) return { text: 'Class 3 Severe Obesity', color: '#7f1d1d', bg: '#fecaca', pctOf95: pctOf95, bmi95: bmi95 };
    if (pctOf95 >= 120) return { text: 'Class 2 Severe Obesity', color: '#dc2626', bg: '#fee2e2', pctOf95: pctOf95, bmi95: bmi95 };
    return { text: 'Obese (Class 1)', color: '#ef4444', bg: '#fee2e2', pctOf95: pctOf95, bmi95: bmi95 };
  }
  if (percentile >= 85) return { text: 'Overweight', color: '#f97316', bg: '#ffedd5', pctOf95: pctOf95, bmi95: bmi95 };
  if (percentile >= 5) return { text: 'Healthy Weight', color: '#10b981', bg: '#d1fae5', pctOf95: pctOf95, bmi95: bmi95 };
  return { text: 'Underweight', color: '#f59e0b', bg: '#fef3c7', pctOf95: pctOf95, bmi95: bmi95 };
}

export function calculateBMIAssessment(lmsData, sex, ageYears, weightKg, heightCm) {
  var bmi = weightKg / Math.pow(heightCm / 100, 2);
  var ageMonths = Math.round(ageYears * 12);
  if (ageMonths < 24) ageMonths = 24;
  if (ageMonths > 240) ageMonths = 240;
  var lms = interpolateLMS(lmsData[sex], ageMonths);
  var result = calcBMIPercentile(bmi, lms.L, lms.M, lms.S);
  var classification = classifyBMI(result.percentile, bmi, lms);
  return {
    ageMonths: ageMonths,
    bmi: bmi,
    z: result.z,
    percentile: result.percentile,
    lms: lms,
    classification: classification
  };
}
