const { fmt, ui, $ } = Admin;

// The revision the page was last drawn from. Every mutation carries it, so two operators
// working at once cannot silently overwrite each other's publish.
let revision = 0;

function featureCard(feature) {
  const mode = feature.source === 'override' ? (feature.enabled ? 'on' : 'off') : 'default';
  return '<section class="card"><div class="card-head split"><div>' +
    '<h2 class="card-title">' + fmt.escape(feature.name) + '</h2>' +
    '<p class="card-note">' + fmt.escape(feature.description) + '</p></div>' +
    ui.tag(feature.enabled ? 'active' : 'off', feature.enabled ? 'ok' : 'idle') + '</div>' +
    '<label class="field"><span>Mode</span>' +
    '<select data-feature-key="' + fmt.escape(feature.key) + '">' +
      '<option value="default"' + (mode === 'default' ? ' selected' : '') + '>Safe default</option>' +
      '<option value="on"' + (mode === 'on' ? ' selected' : '') + '>Forced on</option>' +
      '<option value="off"' + (mode === 'off' ? ' selected' : '') + '>Forced off</option>' +
    '</select></label>' +
    '<div class="chips"><span class="chip mono">' + fmt.escape(feature.key) + '</span>' +
      ui.chip('protocol ' + fmt.number(feature.minimumProtocol) + '+') +
      ui.chip(feature.compatible ? 'server compatible' : 'compatibility blocked',
        feature.compatible ? 'accent' : 'warn') +
      ui.chip(feature.area) + '</div>' +
    '<p class="hint">↳ ' + fmt.escape(feature.recovery) + '</p></section>';
}

Admin.onStatus((status) => {
  const payload = status.features || {};
  const clients = status.clients || [];
  revision = Number(payload.revision || 0);
  const features = payload.features || [];
  const capable = clients.filter((client) =>
    (client.capabilities || []).includes('server_features_v1')).length;

  $('feature-health').innerHTML = ui.tiles([
    ['features active', features.filter((feature) => feature.enabled).length + ' / ' + features.length,
      { icon: 'sliders', tone: 'ok' }],
    ['explicit overrides', features.filter((feature) => feature.source === 'override').length,
      { icon: 'wrench', tone: 'warn' }],
    ['televisions reporting the control plane', capable + ' / ' + clients.length,
      { icon: 'tv', tone: 'info' }],
    ['published revision', 'r' + revision, { icon: 'history', tone: 'note' }],
  ]);

  const safe = $('feature-safe-mode');
  safe.textContent = payload.safeMode ? 'Leave safe mode' : 'Enable safe mode';
  safe.className = payload.safeMode ? '' : 'danger';

  $('feature-state').innerHTML = payload.safeMode
    ? ui.tag('safe mode · optional features off', 'warn')
    : ui.tag('live · revision r' + revision, 'ok');
  $('feature-rollback').disabled = !payload.canRollback;

  // A redraw would take a half-made choice out from under the operator, and the selects are
  // read back wholesale when Publish is pressed.
  const list = $('feature-list');
  if (!Admin.settled(list)) return;
  list.innerHTML = features.map(featureCard).join('') ||
    ui.empty('No server features are registered.');
});

const featureAction = (action, overrides = {}) => Admin.api('/admin/api/features', {
  method: 'POST',
  body: JSON.stringify({ action, expectedRevision: revision, overrides }),
});

Admin.ready(() => {
  $('feature-save').addEventListener('click', () => {
    const overrides = {};
    document.querySelectorAll('[data-feature-key]').forEach((select) => {
      if (select.value === 'on') overrides[select.dataset.featureKey] = true;
      if (select.value === 'off') overrides[select.dataset.featureKey] = false;
    });
    Admin.act(() => featureAction('save', overrides));
  });

  $('feature-safe-mode').addEventListener('click', () => {
    const leaving = $('feature-safe-mode').textContent.startsWith('Leave');
    if (!leaving && !confirm('Disable every optional feature immediately? Core sign-in, ' +
      'browsing and playback remain available.')) return;
    Admin.act(() => featureAction(leaving ? 'leave-safe-mode' : 'safe-mode'));
  });

  $('feature-rollback').addEventListener('click', () => {
    if (!confirm('Restore the previous published feature revision?')) return;
    Admin.act(() => featureAction('rollback'));
  });

  $('feature-reset').addEventListener('click', () => {
    if (!confirm('Clear every override and return all features to their safe software defaults?')) return;
    Admin.act(() => featureAction('reset'));
  });
});
