const DEFAULT_PROBE_NAMES = ['Probe 1', 'Probe 2', 'Probe 3', 'Probe 4'];
const PRESETS = [
  { label: 'Brisket', temp: 203 },
  { label: 'Pork Butt', temp: 205 },
  { label: 'Poultry (breast)', temp: 165 },
  { label: 'Poultry (thigh)', temp: 175 },
  { label: 'Ribs', temp: 203 },
];

let activeSession = null;
let latestReading = null;
let setpoints = [];
let chartInstance = null;

async function api(path, options = {}) {
  const resp = await fetch(path, options);
  if (!resp.ok) throw new Error(`${resp.status} ${resp.statusText}`);
  return resp.json();
}

function formatTime(iso) {
  if (!iso) return '--';
  const d = new Date(iso + (iso.endsWith('Z') ? '' : 'Z'));
  return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
}

function statusClass(connected) {
  return connected ? 'ok' : 'danger';
}

function renderProbeCards(reading, setpoints) {
  const container = document.getElementById('probe-cards');
  container.innerHTML = '';

  const probes = reading?.probes || [];
  const unit = reading?.unit || 'F';

  for (let i = 0; i < 4; i++) {
    const probe = probes[i] || { id: i + 1, name: DEFAULT_PROBE_NAMES[i], temperature: null, connected: false };
    const setpoint = setpoints.find(s => s.probe_number === (i + 1));

    const card = document.createElement('div');
    card.className = `probe-card ${probe.connected ? 'connected' : ''}`;

    const tempDisplay = probe.connected
      ? `<div class="temp">${probe.temperature.toFixed(1)}<span>°${unit}</span></div>`
      : `<div class="temp disconnected">---</div>`;

    const targetDisplay = setpoint
      ? `<div class="target">Target: ${setpoint.label || ''} ${setpoint.target_temp.toFixed(0)}°${unit}</div>`
      : `<div class="target">No target set</div>`;

    card.innerHTML = `
      <div class="header">
        <span class="name">${probe.name || DEFAULT_PROBE_NAMES[i]}</span>
        <span>#${i + 1}</span>
      </div>
      ${targetDisplay}
      ${tempDisplay}
      <div class="footer">
        <span>${probe.connected ? 'Connected' : 'Disconnected'}</span>
      </div>
      <div class="setpoint-editor">
        <select class="preset-select" data-probe="${i + 1}">
          <option value="">Preset...</option>
          ${PRESETS.map(p => `<option value="${p.temp}">${p.label} (${p.temp}°${unit})</option>`).join('')}
          <option value="custom">Custom...</option>
        </select>
        <input type="number" class="custom-target" data-probe="${i + 1}" placeholder="Target °${unit}" value="${setpoint ? setpoint.target_temp : ''}">
        <input type="text" class="target-label" data-probe="${i + 1}" placeholder="Label" value="${setpoint ? setpoint.label : ''}">
        <button class="save-setpoint" data-probe="${i + 1}">Save</button>
      </div>
    `;

    container.appendChild(card);
  }

  // Wire up preset selectors and save buttons.
  document.querySelectorAll('.preset-select').forEach(sel => {
    sel.addEventListener('change', () => {
      const probe = sel.dataset.probe;
      const customInput = document.querySelector(`.custom-target[data-probe="${probe}"]`);
      if (sel.value && sel.value !== 'custom') {
        customInput.value = sel.value;
      }
    });
  });

  document.querySelectorAll('.save-setpoint').forEach(btn => {
    btn.addEventListener('click', async () => {
      const probe = parseInt(btn.dataset.probe, 10);
      const target = parseFloat(document.querySelector(`.custom-target[data-probe="${probe}"]`).value);
      const label = document.querySelector(`.target-label[data-probe="${probe}"]`).value;
      if (isNaN(target)) return;
      await saveSetpoint(probe, label, target);
    });
  });
}

async function saveSetpoint(probeNumber, label, targetTemp) {
  if (!activeSession) return;
  await api(`/api/setpoints/${activeSession.id}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ probe_number: probeNumber, label, target_temp: targetTemp }),
  });
  await loadSetpoints();
  await refreshDashboard();
}

function renderStatusBar(reading) {
  const cydEl = document.getElementById('cyd-status');
  const battEl = document.getElementById('battery-status');
  const sigEl = document.getElementById('signal-status');

  if (!reading) {
    cydEl.textContent = 'CYD unreachable';
    cydEl.className = 'danger';
    return;
  }

  const connected = reading.connected;
  cydEl.textContent = connected ? 'CYD connected' : 'CYD: BLE disconnected';
  cydEl.className = connected ? 'ok' : 'warn';

  battEl.textContent = `Battery: ${reading.battery ?? '--'}%`;

  const rssi = reading.rssi;
  sigEl.textContent = rssi !== undefined ? `Signal: ${rssi} dBm` : 'Signal: WiFi only';
}

async function loadSessions() {
  const sessions = await api('/api/sessions');
  activeSession = sessions.find(s => !s.ended_at) || null;

  const activeEl = document.getElementById('active-session');
  const endBtn = document.getElementById('end-session-btn');

  if (activeSession) {
    activeEl.innerHTML = `
      <strong>${activeSession.name}</strong> started at ${formatTime(activeSession.started_at)}
      <br><small>${activeSession.notes || 'No notes'}</small>
    `;
    endBtn.disabled = false;
  } else {
    activeEl.textContent = 'No active session.';
    endBtn.disabled = true;
  }
}

async function loadSetpoints() {
  if (!activeSession) {
    setpoints = [];
    return;
  }
  setpoints = await api(`/api/setpoints/${activeSession.id}`);
}

async function refreshDashboard() {
  try {
    const status = await api('/api/status');
    latestReading = status.latest_reading;

    // Add probe names from active session if we had stored them; for now use CYD names.
    if (latestReading) {
      // The CYD returns probe names; pass them through.
    }

    renderStatusBar(status.latest_reading);
    renderProbeCards(status.latest_reading, setpoints);
    document.getElementById('last-updated').textContent = `Last updated: ${formatTime(new Date().toISOString())}`;
  } catch (e) {
    console.error('Refresh failed:', e);
    renderStatusBar(null);
  }
}

async function refreshChart() {
  if (!activeSession || !chartInstance) return;
  const range = parseInt(document.getElementById('chart-range').value, 10);
  const data = await api(`/api/readings/${activeSession.id}?minutes=${range}`);

  const labels = data.map(r => formatTime(r.received_at));
  const datasets = [1, 2, 3, 4].map((num, idx) => ({
    label: (latestReading?.probes?.[idx]?.name) || `Probe ${num}`,
    data: data.map(r => r[`probe${num}_temp`]),
    borderColor: ['#ff6b35', '#4caf50', '#2196f3', '#9c27b0'][idx],
    backgroundColor: ['rgba(255,107,53,0.1)', 'rgba(76,175,80,0.1)', 'rgba(33,150,243,0.1)', 'rgba(156,39,176,0.1)'][idx],
    fill: true,
    tension: 0.3,
    spanGaps: true,
  }));

  chartInstance.data.labels = labels;
  chartInstance.data.datasets = datasets;
  chartInstance.update();
}

function initChart() {
  const ctx = document.getElementById('temp-chart').getContext('2d');
  chartInstance = new Chart(ctx, {
    type: 'line',
    data: { labels: [], datasets: [] },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      scales: {
        y: {
          title: { display: true, text: 'Temperature' },
          grid: { color: '#333' },
          ticks: { color: '#aaa' },
        },
        x: {
          grid: { color: '#333' },
          ticks: { color: '#aaa', maxTicksLimit: 8 },
        },
      },
      plugins: {
        legend: { labels: { color: '#f0f0f0' } },
      },
    },
  });
}

document.getElementById('new-session-form').addEventListener('submit', async (e) => {
  e.preventDefault();
  const name = document.getElementById('session-name').value;
  const notes = document.getElementById('session-notes').value;
  await api('/api/sessions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name, notes }),
  });
  document.getElementById('session-name').value = '';
  document.getElementById('session-notes').value = '';
  await loadSessions();
  await loadSetpoints();
  await refreshChart();
});

document.getElementById('end-session-btn').addEventListener('click', async () => {
  if (!activeSession) return;
  await api(`/api/sessions/${activeSession.id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ end: true }),
  });
  await loadSessions();
  await loadSetpoints();
  await refreshChart();
});

document.getElementById('refresh-chart-btn').addEventListener('click', refreshChart);
document.getElementById('chart-range').addEventListener('change', refreshChart);

async function init() {
  initChart();
  await loadSessions();
  await loadSetpoints();
  await refreshDashboard();
  await refreshChart();

  setInterval(async () => {
    await refreshDashboard();
  }, 5000);

  setInterval(async () => {
    if (activeSession) await refreshChart();
  }, 30000);
}

init();
