// Calendar tab: view/week-start settings, per-user opt-in, and the
// rendered preview. Extracted from frame_config.js when the Calendar
// card became its own tab (window.FRAME_API is set by the template;
// checkboxes are always sent explicitly as "true"/"false").

// Week-view-only settings (days/layout/start-offset) only matter when
// View is actually "Week"; "Week starts on" also matters for Month, so
// it gets its own, slightly looser condition. The start-offset row is
// further gated on the day count -- it's meaningless at the default 7
// days, where "Week starts on" governs instead (see
// calendar_render.py's _build_week).
function updateCalendarFieldVisibility() {
  const view = document.getElementById('calendar_view').value;
  const days = Number(document.getElementById('calendar_week_days').value);
  const isWeek = view === 'week';
  document.getElementById('calendar-week-start-row').style.display =
    (view === 'week' || view === 'month') ? '' : 'none';
  document.getElementById('calendar-week-days-row').style.display = isWeek ? '' : 'none';
  document.getElementById('calendar-week-layout-row').style.display = isWeek ? '' : 'none';
  document.getElementById('calendar-week-offset-row').style.display = (isWeek && days !== 7) ? '' : 'none';
}
document.getElementById('calendar_view').addEventListener('change', updateCalendarFieldVisibility);
document.getElementById('calendar_week_days').addEventListener('input', updateCalendarFieldVisibility);
updateCalendarFieldVisibility();

document.getElementById('calendar-config-form').addEventListener('submit', async (e) => {
  e.preventDefault();
  const body = new URLSearchParams({
    calendar_view: document.getElementById('calendar_view').value,
    calendar_week_start: document.getElementById('calendar_week_start').value,
    calendar_week_days: document.getElementById('calendar_week_days').value,
    calendar_week_layout: document.getElementById('calendar_week_layout').value,
    calendar_week_start_offset: document.getElementById('calendar_week_start_offset').value,
  });
  try {
    const resp = await fetch(`${window.FRAME_API}/config`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body,
    });
    if (!resp.ok) throw new Error(await apiError(resp));
    showStatus(true, 'Saved.');
    loadCalendarPreview();
  } catch (e) {
    showStatus(false, e.message);
  }
});

// Each calendar's own include/mute toggle -- auto-saves on change, not
// batched into the form above, since it's a data-sharing choice (see
// api_frames.py's /calendar-select), not a frame-wide setting. Works the
// same element for your own calendars (full add/remove) and other
// people's (mute only) -- the server enforces which direction is allowed
// and this just reverts the checkbox with an error message if rejected.
document.querySelectorAll('.calendar-toggle').forEach((el) => {
  el.addEventListener('change', async () => {
    try {
      const resp = await fetch(`${window.FRAME_API}/calendar-select`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          user_id: Number(el.dataset.userId),
          calendar_key: el.dataset.key,
          calendar_label: el.dataset.label,
          included: el.checked,
        }),
      });
      if (!resp.ok) throw new Error(await apiError(resp));
      showStatus(true, el.checked ? 'Calendar included on this frame.' : 'Calendar removed from this frame.');
    } catch (e) {
      el.checked = !el.checked;
      showStatus(false, e.message);
    }
  });
});

// Per-calendar color pin -- owner-only (the server enforces it; these
// buttons only ever render for the viewer's own calendars anyway, see
// frame_calendar.html). Clicking the currently-selected swatch again has
// no special "toggle off" behavior -- use the explicit Auto button.
document.querySelectorAll('.calendar-color-picker').forEach((picker) => {
  const key = picker.dataset.key;
  picker.querySelectorAll('.color-swatch').forEach((btn) => {
    btn.addEventListener('click', async () => {
      const colorIndex = btn.dataset.index === '' ? null : Number(btn.dataset.index);
      try {
        const resp = await fetch(`${window.FRAME_API}/calendar-color`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ calendar_key: key, color_index: colorIndex }),
        });
        if (!resp.ok) throw new Error(await apiError(resp));
        picker.querySelectorAll('.color-swatch').forEach((el) => el.classList.remove('selected'));
        btn.classList.add('selected');
        showStatus(true, 'Color saved.');
        loadCalendarPreview();
      } catch (e) {
        showStatus(false, e.message);
      }
    });
  });
});

document.getElementById('weather-config-form').addEventListener('submit', async (e) => {
  e.preventDefault();
  const body = new URLSearchParams({
    calendar_weather_enabled: String(document.getElementById('weather_enabled').checked),
    calendar_weather_units: document.getElementById('weather_units').value,
  });
  try {
    const resp = await fetch(`${window.FRAME_API}/config`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body,
    });
    if (!resp.ok) throw new Error(await apiError(resp));
    showStatus(true, 'Saved.');
    loadCalendarPreview();
  } catch (e) {
    showStatus(false, e.message);
  }
});

function addWeatherCityRow(label) {
  const list = document.getElementById('weather-city-list');
  const empty = document.getElementById('weather-city-empty');
  if (empty) empty.remove();
  const li = document.createElement('li');
  li.className = 'checkbox-row';
  li.style.cssText = 'justify-content: space-between; margin-top: 6px;';
  const span = document.createElement('span');
  span.textContent = label;
  const btn = document.createElement('button');
  btn.type = 'button';
  btn.className = 'btn-inline secondary weather-city-remove';
  btn.dataset.label = label;
  btn.textContent = 'Remove';
  btn.addEventListener('click', removeWeatherCity);
  li.appendChild(span);
  li.appendChild(btn);
  list.appendChild(li);
}

async function removeWeatherCity(e) {
  const label = e.target.dataset.label;
  try {
    const resp = await fetch(`${window.FRAME_API}/weather-cities/remove`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ label }),
    });
    if (!resp.ok) throw new Error(await apiError(resp));
    e.target.closest('li').remove();
    const list = document.getElementById('weather-city-list');
    if (!list.querySelector('li')) {
      list.innerHTML = '<li class="sub" id="weather-city-empty">No cities added yet.</li>';
    }
    showStatus(true, `${label} removed.`);
    loadCalendarPreview();
  } catch (e) {
    showStatus(false, e.message);
  }
}
document.querySelectorAll('.weather-city-remove').forEach((el) => el.addEventListener('click', removeWeatherCity));

document.getElementById('weather-city-add').addEventListener('click', async () => {
  const input = document.getElementById('weather-city-input');
  const name = input.value.trim();
  if (!name) return;
  try {
    const resp = await fetch(`${window.FRAME_API}/weather-cities/add`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name }),
    });
    if (!resp.ok) throw new Error(await apiError(resp));
    const data = await resp.json();
    addWeatherCityRow(data.city.label);
    input.value = '';
    showStatus(true, `Added ${data.city.label}.`);
    loadCalendarPreview();
  } catch (e) {
    showStatus(false, e.message);
  }
});

document.getElementById('tasks_enabled').addEventListener('change', async (e) => {
  const el = e.target;
  try {
    const resp = await fetch(`${window.FRAME_API}/config`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({ calendar_tasks_enabled: String(el.checked) }),
    });
    if (!resp.ok) throw new Error(await apiError(resp));
    showStatus(true, 'Saved.');
    loadCalendarPreview();
  } catch (e) {
    el.checked = !el.checked;
    showStatus(false, e.message);
  }
});

// Rewrites #tasks-current-source in place instead of telling the user
// to reload -- the API always assigns a successful "set" to the caller
// (see api_tasks_source), so after either action we already know
// exactly what the new state is without asking the server again.
function renderTasksCurrentSource(label) {
  const container = document.getElementById('tasks-current-source');
  container.innerHTML = '';
  if (!label) return; // matches the template's no-tasks_source branch: nothing rendered
  const p = document.createElement('p');
  p.className = 'sub';
  p.style.marginTop = '10px';
  p.append('Currently using your ');
  const labelEl = document.createElement('strong');
  labelEl.textContent = label;
  p.append(labelEl, ' list. ');
  const clearBtn = document.createElement('button');
  clearBtn.type = 'button';
  clearBtn.className = 'btn-inline secondary';
  clearBtn.id = 'tasks-source-clear';
  clearBtn.textContent = 'Clear';
  clearBtn.addEventListener('click', clearTasksSource);
  p.append(clearBtn);
  container.append(p);
}

// Choosing one of your own CalDAV task lists as this frame's source --
// owner-only (see api_frames.py's api_tasks_source), so these radios
// only ever render for the viewer's own calendars anyway.
document.querySelectorAll('.tasks-source-choice').forEach((el) => {
  el.addEventListener('change', async () => {
    try {
      const resp = await fetch(`${window.FRAME_API}/tasks-source`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ calendar_key: el.dataset.key }),
      });
      if (!resp.ok) throw new Error(await apiError(resp));
      showStatus(true, 'Task list saved.');
      const labelEl = el.closest('li').querySelector('label');
      renderTasksCurrentSource(labelEl ? labelEl.textContent.trim() : '');
      loadCalendarPreview();
    } catch (e) {
      showStatus(false, e.message);
    }
  });
});

async function clearTasksSource() {
  try {
    const resp = await fetch(`${window.FRAME_API}/tasks-source`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ calendar_key: null }),
    });
    if (!resp.ok) throw new Error(await apiError(resp));
    showStatus(true, 'Task list cleared.');
    renderTasksCurrentSource(null);
    document.querySelectorAll('.tasks-source-choice').forEach((r) => { r.checked = false; });
    loadCalendarPreview();
  } catch (e) {
    showStatus(false, e.message);
  }
}

const tasksSourceClear = document.getElementById('tasks-source-clear');
if (tasksSourceClear) {
  tasksSourceClear.addEventListener('click', clearTasksSource);
}

function loadCalendarPreview() {
  document.getElementById('calendar-preview').src = `${window.FRAME_API}/preview/calendar?_=${Date.now()}`;
}
document.getElementById('calendar-preview-refresh').addEventListener('click', loadCalendarPreview);
loadCalendarPreview();

async function takeControl() {
  try {
    const resp = await fetch(`${window.FRAME_API}/take-control`, { method: 'POST' });
    if (!resp.ok) throw new Error(await apiError(resp));
    showStatus(true, 'You have control now.');
    loadControl();
  } catch (e) {
    showStatus(false, e.message);
  }
}

async function loadControl() {
  const banner = document.getElementById('control-banner');
  try {
    const resp = await fetch(`${window.FRAME_API}/queue`);
    if (!resp.ok) return; // unconfigured frame: control still works via 409s
    const data = await resp.json();
    if (data.control && !data.control.you) {
      banner.style.display = 'flex';
      document.getElementById('control-holder').textContent = data.control.controller
        ? `${data.control.controller} currently has control of this frame.`
        : 'Nobody has control of this frame yet.';
    } else {
      banner.style.display = 'none';
    }
  } catch (e) { /* banner is best-effort */ }
}

document.getElementById('take-control').addEventListener('click', takeControl);
loadControl();
