import { MODES, PK_MODELS, CLINICAL_THRESHOLDS, APP_VERSION, generateSimulationData, processTimelineEvents } from './pkCore.js';
import { adjustChartYScale, updateChartAnnotations } from './chartManager.js';
import { initCalculatorUI } from './calculator.js';
import { exportSimulationToCSV } from './csvExport.js';
import { initI18n, getCurrentLang, t } from './i18n.js';

let currentMode = MODES.ESKETAMINE;
let pkChart = null;
let currentSimulationData = null;

const THEME_STORAGE_KEY = 'keta_theme';
const THEMES = ['dark', 'light', 'monokai'];

let timerMin = 5;
let timespanCount = 60;

function buildTimelineInputs(interval, steps) {
  return Array.from({ length: steps + 1 }, (_, i) => ({
    time: i * interval,
    bolusMg: 0,
    perfRate: null
  }));
}

let timelineInputs = buildTimelineInputs(timerMin, timespanCount);

function updateVersionDisplay() {
  const versionEl = document.querySelector('[data-i18n="app.version"]');
  if (versionEl) {
    versionEl.textContent = t('app.version', { version: APP_VERSION });
  }
}

function updateDynamicLabels() {
  const total = timerMin * timespanCount;

  const titleEl = document.querySelector('[data-i18n="timeline.title"]');
  if (titleEl) titleEl.textContent = t('timeline.title', { total });

  const summaryEl = document.querySelector('[data-i18n="table.summary_title"]');
  if (summaryEl) summaryEl.textContent = t('table.summary_title', { total });

  const totalEl = document.getElementById('totalTimespanDisplay');
  if (totalEl) totalEl.textContent = t('patient.total_label', { total });
}

function getStoredTheme() {
  const stored = localStorage.getItem(THEME_STORAGE_KEY);
  return THEMES.includes(stored) ? stored : 'dark';
}

function applyTheme(theme) {
  const resolved = THEMES.includes(theme) ? theme : 'dark';
  document.documentElement.setAttribute('data-theme', resolved);
  localStorage.setItem(THEME_STORAGE_KEY, resolved);
  refreshChartTheme();
}

function refreshChartTheme() {
  if (!pkChart) return;
  const styles = getComputedStyle(document.documentElement);
  const gridColor = styles.getPropertyValue('--kt-chart-grid').trim();
  const textColor = styles.getPropertyValue('--kt-chart-text').trim();
  const legendColor = styles.getPropertyValue('--kt-chart-legend').trim();

  pkChart.options.scales.y.title.color = textColor;
  pkChart.options.scales.y.grid.color = gridColor;
  pkChart.options.scales.x.title.color = textColor;
  pkChart.options.scales.x.grid.color = gridColor;
  pkChart.options.plugins.legend.labels.color = legendColor;

  // The clinical zone text colors also depend on the theme (see chartManager.js)
  updateChartAnnotations(pkChart, currentMode, pkChart.options.scales.y.max);
  pkChart.update();
}

function readPositiveInt(el, fallback, max = Infinity) {
  const parsed = parseInt(el.value.trim(), 10);
  if (isNaN(parsed) || parsed < 1) return fallback;
  return Math.min(parsed, max);
}

function enforceIntegerInput(el) {
  el?.addEventListener('input', () => {
    const cleaned = el.value.replace(/[^\d]/g, '');
    if (cleaned !== el.value) el.value = cleaned;
  });
}

function rebuildTimeline() {
  timelineInputs = buildTimelineInputs(timerMin, timespanCount);
  pkChart.data.labels = timelineInputs.map(d => `${d.time}'`);
  renderTimelineGrid();
  updateDynamicLabels();
  updateSimulation();
}

document.addEventListener('DOMContentLoaded', async () => {
  applyTheme(getStoredTheme());

  await initI18n();
  updateVersionDisplay();

  const selectLang = document.getElementById('selectLang');
  if (selectLang) {
    selectLang.value = getCurrentLang();
    selectLang.addEventListener('change', async (e) => {
      await initI18n(e.target.value);
      updateVersionDisplay();
      renderTimelineGrid();
      updateDynamicLabels();
      updateSimulation();
    });
  }

  const selectTheme = document.getElementById('selectTheme');
  if (selectTheme) {
    selectTheme.value = getStoredTheme();
    selectTheme.addEventListener('change', (e) => applyTheme(e.target.value));
  }

  const timerInput = document.getElementById('timerInput');
  const timespanInput = document.getElementById('timespanInput');
  if (timerInput) {
    timerInput.value = timerMin;
    enforceIntegerInput(timerInput);
    timerInput.addEventListener('change', () => {
      timerMin = readPositiveInt(timerInput, timerMin);
      timerInput.value = timerMin;
      rebuildTimeline();
    });
  }
  if (timespanInput) {
    timespanInput.value = timespanCount;
    enforceIntegerInput(timespanInput);
    timespanInput.addEventListener('change', () => {
      timespanCount = readPositiveInt(timespanInput, timespanCount, 500);
      timespanInput.value = timespanCount;
      rebuildTimeline();
    });
  }

  initChart();
  renderTimelineGrid();
  updateDynamicLabels();
  initCalculatorUI();
  setupEventListeners();
  updateSimulation();
});

function initChart() {
  const ctx = document.getElementById('pkChart').getContext('2d');
  const styles = getComputedStyle(document.documentElement);
  const gridColor = styles.getPropertyValue('--kt-chart-grid').trim();
  const textColor = styles.getPropertyValue('--kt-chart-text').trim();
  const legendColor = styles.getPropertyValue('--kt-chart-legend').trim();

  pkChart = new Chart(ctx, {
    type: 'line',
    data: {
      labels: timelineInputs.map(d => `${d.time}'`),
      datasets: []
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      scales: {
        y: {
          beginAtZero: true,
          max: CLINICAL_THRESHOLDS[currentMode].maxScale,
          title: { display: true, text: 'Cp (ng/mL)', color: textColor },
          grid: { color: gridColor }
        },
        x: {
          title: { display: true, text: 'Temps (minutes)', color: textColor },
          grid: { color: gridColor }
        }
      },
      plugins: {
        legend: { labels: { color: legendColor } },
        annotation: { annotations: {} }
      }
    }
  });
}

function updateSimulation() {
  const weightInput = document.getElementById('patientWeight');
  const weight = parseFloat(weightInput?.value) || 70;
  const unit = document.getElementById('infusionUnitSelect')?.value || 'mg_kg_h';

  // Weight warning (30-120 kg)
  const weightWarning = document.getElementById('weightWarning');
  if (weightWarning) {
    if (weight < 30 || weight > 120) {
      weightWarning.classList.remove('hidden');
    } else {
      weightWarning.classList.add('hidden');
    }
  }

  const datasets = [];
  const dominoData = document.getElementById('chkDomino')?.checked
    ? generateSimulationData({ model: PK_MODELS.DOMINO, weightKg: weight, timelineInputs, infusionUnit: unit })
    : null;

  const clementsData = document.getElementById('chkClements')?.checked
    ? generateSimulationData({ model: PK_MODELS.CLEMENTS, weightKg: weight, timelineInputs, infusionUnit: unit })
    : null;

  const kampData = document.getElementById('chkKamp')?.checked
    ? generateSimulationData({ model: PK_MODELS.KAMP, weightKg: weight, timelineInputs, infusionUnit: unit })
    : null;

  if (dominoData) {
    datasets.push({
      label: PK_MODELS.DOMINO.name,
      data: dominoData.map(d => d.cp),
      borderColor: PK_MODELS.DOMINO.color,
      borderWidth: 3,
      tension: 0.2
    });
  }

  if (clementsData) {
    datasets.push({
      label: PK_MODELS.CLEMENTS.name,
      data: clementsData.map(d => d.cp),
      borderColor: PK_MODELS.CLEMENTS.color,
      borderWidth: 3,
      tension: 0.2
    });
  }

  if (kampData) {
    datasets.push({
      label: PK_MODELS.KAMP.name,
      data: kampData.map(d => d.cp),
      borderColor: PK_MODELS.KAMP.color,
      borderWidth: 3,
      tension: 0.2
    });
  }

  pkChart.data.datasets = datasets;
  adjustChartYScale(pkChart, currentMode, datasets);
  pkChart.update();

  currentSimulationData = {
    timeline: processTimelineEvents(timelineInputs, weight, unit),
    domino: dominoData,
    clements: clementsData,
    kamp: kampData
  };

  updateTimelineGridStyles();
  renderDataTable(currentSimulationData);
}

function renderDataTable(simulationData) {
  const tbody = document.getElementById('dataTableBody');
  if (!tbody || !simulationData) return;

  tbody.innerHTML = '';

  simulationData.timeline.forEach((item, index) => {
    const row = document.createElement('tr');
    row.className = index % 2 === 0 ? 'bg-[var(--kt-row-alt-1)]' : 'bg-[var(--kt-row-alt-2)]';
    
    const dominoCp = (simulationData.domino && simulationData.domino[index]) ? Math.round(simulationData.domino[index].cp) : '-';
    const clementsCp = (simulationData.clements && simulationData.clements[index]) ? Math.round(simulationData.clements[index].cp) : '-';
    const kampCp = (simulationData.kamp && simulationData.kamp[index]) ? Math.round(simulationData.kamp[index].cp) : '-';

    row.innerHTML = `
      <td class="px-3 py-1.5 font-bold">${item.time} min</td>
      <td class="px-3 py-1.5">${item.bolusMg ? item.bolusMg : '-'}</td>
      <td class="px-3 py-1.5">${item.infusionRate !== null && item.infusionRate !== undefined ? item.infusionRate : '0'}</td>
      <td class="px-3 py-1.5 text-cyan-300 font-bold">${dominoCp}</td>
      <td class="px-3 py-1.5 text-emerald-300 font-bold">${clementsCp}</td>
      <td class="px-3 py-1.5 text-purple-300 font-bold">${kampCp}</td>
    `;
    tbody.appendChild(row);
  });
}

function renderTimelineGrid() {
  const container = document.getElementById('timelineGrid');
  if (!container) return;

  container.innerHTML = '';

  timelineInputs.forEach((item, idx) => {
    const col = document.createElement('div');
    col.className = 'flex-1 bg-[var(--kt-surface-3)] border border-[var(--kt-border-soft)] rounded-xl p-2 text-center text-xs flex flex-col gap-1.5 min-w-[85px]';

    col.innerHTML = `
      <div class="font-bold text-amber-400 border-b border-[var(--kt-border-soft)] pb-1">${item.time} min</div>
      <div>
        <span class="text-[10px] text-[var(--kt-text-3)] block mb-0.5">${t('timeline.bolus')}</span>
        <input type="number" step="any" data-idx="${idx}" data-field="bolusMg" value="" placeholder="0" class="w-full bg-[var(--kt-surface-2)] border border-[var(--kt-border)] text-center rounded text-[var(--kt-text-1)] py-1 outline-none focus:border-amber-500">
      </div>
      <div>
        <span class="text-[10px] text-[var(--kt-text-3)] block mb-0.5">${t('timeline.perf')}</span>
        <input type="number" step="any" data-idx="${idx}" data-field="perfRate" value="" placeholder="0" class="w-full border text-center rounded py-1 outline-none transition-colors">
      </div>
    `;
    container.appendChild(col);
  });

  updateTimelineGridStyles();
}

function updateTimelineGridStyles() {
  const container = document.getElementById('timelineGrid');
  if (!container) return;

  const weight = parseFloat(document.getElementById('patientWeight')?.value) || 70;
  const unit = document.getElementById('infusionUnitSelect')?.value || 'mg_kg_h';
  const processed = processTimelineEvents(timelineInputs, weight, unit);

  const perfInputs = container.querySelectorAll('input[data-field="perfRate"]');
  const bolusInputs = container.querySelectorAll('input[data-field="bolusMg"]');

  perfInputs.forEach((input) => {
    const idx = parseInt(input.dataset.idx, 10);
    const event = processed[idx];
    const isFocused = (document.activeElement === input);

    if (event.isExplicit) {
      input.className = 'w-full border text-center rounded py-1 outline-none transition-colors bg-cyan-950/90 border-cyan-400 text-cyan-200 font-bold focus:border-cyan-300 shadow-sm shadow-cyan-950';
      if (!isFocused) {
        input.value = timelineInputs[idx].perfRate !== null ? timelineInputs[idx].perfRate : '';
      }
    } else {
      input.className = 'w-full border text-center rounded py-1 outline-none transition-colors bg-[var(--kt-surface-3)] border-[var(--kt-border-soft)] text-[var(--kt-text-3)] font-normal italic focus:border-amber-500';
      if (!isFocused) {
        input.value = event.infusionRate > 0 ? event.infusionRate : '';
      }
    }
  });

  bolusInputs.forEach((input) => {
    const idx = parseInt(input.dataset.idx, 10);
    const isFocused = (document.activeElement === input);
    if (!isFocused) {
      input.value = timelineInputs[idx].bolusMg || '';
    }
  });
}

function setupEventListeners() {
  document.getElementById('timelineGrid')?.addEventListener('input', (e) => {
    const idx = e.target.dataset.idx;
    const field = e.target.dataset.field;
    if (idx !== undefined && field) {
      const rawVal = e.target.value.trim().replace(',', '.');
      
      if (field === 'perfRate') {
        if (rawVal === '') {
          timelineInputs[idx].perfRate = null;
        } else {
          const parsed = parseFloat(rawVal);
          timelineInputs[idx].perfRate = isNaN(parsed) ? null : parsed;
        }
      } else {
        if (rawVal === '') {
          timelineInputs[idx].bolusMg = 0;
        } else {
          const parsed = parseFloat(rawVal);
          timelineInputs[idx].bolusMg = isNaN(parsed) ? 0 : parsed;
        }
      }
      
      updateSimulation();
    }
  });

  document.getElementById('btnEsk')?.addEventListener('click', () => setMode(MODES.ESKETAMINE));
  document.getElementById('btnRac')?.addEventListener('click', () => setMode(MODES.RACEMIQUE));

  ['patientName', 'patientWeight', 'infusionUnitSelect', 'chkDomino', 'chkClements', 'chkKamp'].forEach(id => {
    document.getElementById(id)?.addEventListener('change', updateSimulation);
    document.getElementById(id)?.addEventListener('input', updateSimulation);
  });

  document.getElementById('btnRaz')?.addEventListener('click', () => {
    timelineInputs.forEach(item => { item.bolusMg = 0; item.perfRate = null; });
    const container = document.getElementById('timelineGrid');
    if (container) {
      container.querySelectorAll('input').forEach(inp => inp.value = '');
    }
    updateSimulation();
  });

  const triggerExport = () => {
    if (!currentSimulationData) {
      updateSimulation();
    }
    const name = document.getElementById('patientName')?.value || '';
    const weight = parseFloat(document.getElementById('patientWeight')?.value) || 70;
    const unit = document.getElementById('infusionUnitSelect')?.value || 'mg_kg_h';

    exportSimulationToCSV(currentSimulationData, {
      name: name,
      weight: weight,
      infusionUnit: unit
    });
  };

  document.getElementById('btnExportCSVNav')?.addEventListener('click', triggerExport);
  document.getElementById('btnExportCSV')?.addEventListener('click', triggerExport);
}

function setMode(mode) {
  currentMode = mode;
  const btnEsk = document.getElementById('btnEsk');
  const btnRac = document.getElementById('btnRac');

  if (mode === MODES.ESKETAMINE) {
    btnEsk.className = 'px-4 py-1.5 rounded-lg text-xs font-bold bg-amber-500 text-slate-950 shadow-md shadow-amber-500/30';
    btnRac.className = 'px-4 py-1.5 rounded-lg text-xs font-bold text-[var(--kt-text-3)] hover:text-[var(--kt-text-1)]';
  } else {
    btnRac.className = 'px-4 py-1.5 rounded-lg text-xs font-bold bg-fuchsia-500 text-slate-950 shadow-md shadow-fuchsia-500/30';
    btnEsk.className = 'px-4 py-1.5 rounded-lg text-xs font-bold text-[var(--kt-text-3)] hover:text-[var(--kt-text-1)]';
  }
  updateSimulation();
}