'use strict';

// ── State ─────────────────────────────────────────────────────────────────────

const state = {
  installed: false,
  running:   false,
  config:    { enabled: false, pools: [] },
  ifaces:    [],   // all non-lo interfaces from the API
  dirty:     false,
  editIface: null, // interface name being edited in modal
};

// ── API ───────────────────────────────────────────────────────────────────────

async function api(method, path, body) {
  const res = await fetch(path, {
    method,
    headers: body ? { 'Content-Type': 'application/json' } : {},
    body: body ? JSON.stringify(body) : undefined,
  });
  const json = await res.json();
  if (!res.ok || !json.success) throw new Error(json.error || `HTTP ${res.status}`);
  return json.data;
}

// ── Helpers ───────────────────────────────────────────────────────────────────

function fmtLease(sec) {
  if (!sec || sec <= 0) return '24 ч';
  if (sec < 3600)  return `${sec} с`;
  if (sec < 86400) return `${(sec/3600).toFixed(0)} ч`;
  return `${(sec/86400).toFixed(0)} д`;
}

function poolForIface(name) {
  return state.config.pools.find(p => p.interface === name) || null;
}

// ── Render ────────────────────────────────────────────────────────────────────

function render() {
  // Not-installed banner
  document.getElementById('notInstalledBanner').classList.toggle('hidden', state.installed);

  // Status bar
  const svcBadge = document.getElementById('svcStatus');
  svcBadge.textContent = state.running ? 'работает' : 'остановлен';
  svcBadge.className   = `svc-badge ${state.running ? 'running' : 'stopped'}`;

  document.getElementById('enableToggle').checked = state.config.enabled;
  document.getElementById('applyBtn').disabled    = !state.installed || !state.dirty;

  // Pools grid
  const grid    = document.getElementById('poolsGrid');
  const loading = document.getElementById('poolsLoading');
  const noIface = document.getElementById('noIfaces');

  loading.classList.add('hidden');

  // interfaces eligible for DHCP: no gateway
  const eligible = state.ifaces.filter(i => !i.has_gateway);

  if (eligible.length === 0) {
    grid.classList.add('hidden');
    noIface.classList.remove('hidden');
    return;
  }
  noIface.classList.add('hidden');
  grid.classList.remove('hidden');

  grid.innerHTML = '';

  // Show ALL interfaces (both eligible and WAN), so the user sees the full picture
  state.ifaces.forEach(iface => {
    grid.appendChild(buildPoolCard(iface));
  });
}

function buildPoolCard(iface) {
  const pool    = poolForIface(iface.name);
  const isWAN   = iface.has_gateway;
  const enabled = pool?.enabled ?? false;

  const card = document.createElement('div');
  card.className = 'pool-card' + (isWAN ? ' pool-card--wan' : '') + (enabled ? ' pool-card--active' : '');
  card.innerHTML = `
    <div class="pool-header">
      <div class="pool-iface">
        <span class="state-dot ${iface.ipv4 ? 'up' : 'unknown'}"></span>
        <span class="pool-iface-name">${iface.name}</span>
        ${isWAN ? '<span class="tag-gw">WAN</span>' : ''}
        ${(!isWAN && enabled) ? '<span class="tag-active">DHCP активен</span>' : ''}
      </div>
      ${!isWAN ? `<button class="btn btn-primary btn-sm" data-edit="${iface.name}">
        ${pool ? '⚙ Изменить' : '+ Добавить пул'}
      </button>` : ''}
    </div>

    <div class="pool-info">
      ${iface.ipv4
        ? `<div class="info-row"><span class="info-label">IP</span>
             <span class="info-val">${iface.ipv4}${iface.ipv4_mask ? ' / ' + iface.ipv4_mask : ''}</span></div>`
        : `<div class="info-row"><span class="info-val none">нет IP-адреса</span></div>`}

      ${isWAN
        ? `<div class="info-row"><span class="info-val muted">Интерфейс имеет шлюз — DHCP не раздаётся</span></div>`
        : pool
          ? `
          <div class="info-row">
            <span class="info-label">Подсеть</span>
            <span class="info-val">${pool.subnet} / ${pool.netmask || '?'}</span>
          </div>
          <div class="info-row">
            <span class="info-label">Диапазон</span>
            <span class="info-val">${pool.range_start || '—'} — ${pool.range_end || '—'}</span>
          </div>
          <div class="info-row">
            <span class="info-label">Шлюз</span>
            <span class="info-val">${pool.router || '—'}</span>
          </div>
          <div class="info-row">
            <span class="info-label">DNS</span>
            <span class="info-val">${(pool.dns || []).join(', ') || '—'}</span>
          </div>
          <div class="info-row">
            <span class="info-label">Аренда</span>
            <span class="info-val">${fmtLease(pool.lease_time)}</span>
          </div>
          `
          : `<div class="info-row"><span class="info-val muted">Пул не настроен</span></div>`
      }
    </div>
    ${(!isWAN && pool) ? `
    <div class="pool-footer">
      <label class="checkbox-label" style="font-size:.83rem">
        <input type="checkbox" class="pool-enabled-chk" data-iface="${iface.name}" ${enabled ? 'checked' : ''}>
        <span>Активен</span>
      </label>
      <button class="btn btn-danger btn-sm" data-remove="${iface.name}" style="margin-left:auto">Удалить пул</button>
    </div>` : ''}
  `;

  return card;
}

// ── Load data ─────────────────────────────────────────────────────────────────

async function loadAll() {
  try {
    const [status, data] = await Promise.all([
      api('GET', '/api/dhcp/status'),
      api('GET', '/api/dhcp/config'),
    ]);
    state.installed = status.installed;
    state.running   = status.running;
    state.config    = data.config   || { enabled: false, pools: [] };
    state.ifaces    = data.interfaces || [];
    state.dirty     = false;
    render();
  } catch (e) {
    showToast('Ошибка загрузки: ' + e.message, 'error');
  }
}

// ── Apply ─────────────────────────────────────────────────────────────────────

async function saveConfig() {
  try {
    await api('POST', '/api/dhcp/config', state.config);
    state.dirty = false;
    render();
  } catch (e) {
    showToast('Ошибка сохранения: ' + e.message, 'error');
    throw e;
  }
}

async function applyConfig() {
  const btn = document.getElementById('applyBtn');
  btn.disabled = true;
  btn.textContent = 'Применяю...';
  try {
    await saveConfig();
    await api('POST', '/api/dhcp/apply');
    showToast('DHCP конфигурация применена', 'success');
    await loadAll();
  } catch (e) {
    showToast('Ошибка применения: ' + e.message, 'error');
  } finally {
    btn.disabled = false;
    btn.textContent = 'Применить';
  }
}

// ── Pool modal ────────────────────────────────────────────────────────────────

function openPoolModal(ifaceName) {
  state.editIface = ifaceName;
  document.getElementById('poolModalTitle').textContent = `Пул для ${ifaceName}`;
  document.getElementById('pIface').value = ifaceName;

  const existing = poolForIface(ifaceName);
  const iface    = state.ifaces.find(i => i.name === ifaceName);

  // Defaults: auto-fill subnet/netmask/router from interface IP if possible
  if (existing) {
    document.getElementById('pEnabled').checked       = existing.enabled;
    document.getElementById('pSubnet').value          = existing.subnet      || '';
    document.getElementById('pNetmask').value         = existing.netmask     || '';
    document.getElementById('pRangeStart').value      = existing.range_start || '';
    document.getElementById('pRangeEnd').value        = existing.range_end   || '';
    document.getElementById('pRouter').value          = existing.router      || '';
    document.getElementById('pDNS').value             = (existing.dns || []).join(' ');
    document.getElementById('pLease').value           = existing.lease_time  || 86400;
  } else {
    document.getElementById('poolForm').reset();
    document.getElementById('pEnabled').checked = true;
    // auto-suggest subnet and router from interface address
    if (iface?.ipv4) {
      const parts = iface.ipv4.split('.');
      const subnet = parts.slice(0, 3).join('.') + '.0';
      document.getElementById('pSubnet').value  = subnet;
      document.getElementById('pRouter').value  = iface.ipv4;
      const rangeBase = parts.slice(0, 3).join('.');
      document.getElementById('pRangeStart').value = rangeBase + '.100';
      document.getElementById('pRangeEnd').value   = rangeBase + '.200';
    }
    if (iface?.ipv4_mask) {
      document.getElementById('pNetmask').value = iface.ipv4_mask;
    }
    document.getElementById('pLease').value = 86400;
  }

  document.getElementById('poolModal').classList.remove('hidden');
}

function closePoolModal() {
  document.getElementById('poolModal').classList.add('hidden');
  state.editIface = null;
}

function savePool() {
  const ifaceName = document.getElementById('pIface').value;
  if (!ifaceName) return;

  const pool = {
    interface:   ifaceName,
    enabled:     document.getElementById('pEnabled').checked,
    subnet:      document.getElementById('pSubnet').value.trim(),
    netmask:     document.getElementById('pNetmask').value.trim(),
    range_start: document.getElementById('pRangeStart').value.trim(),
    range_end:   document.getElementById('pRangeEnd').value.trim(),
    router:      document.getElementById('pRouter').value.trim(),
    dns:         document.getElementById('pDNS').value.trim().split(/\s+/).filter(Boolean),
    lease_time:  parseInt(document.getElementById('pLease').value, 10) || 86400,
  };

  if (!pool.subnet || !pool.netmask) {
    showToast('Укажите подсеть и маску', 'error');
    return;
  }

  // upsert
  const idx = state.config.pools.findIndex(p => p.interface === ifaceName);
  if (idx >= 0) {
    state.config.pools[idx] = pool;
  } else {
    state.config.pools.push(pool);
  }

  state.dirty = true;
  closePoolModal();
  render();
  showToast('Пул обновлён. Нажмите «Применить» чтобы активировать.', 'info');
}

function removePool(ifaceName) {
  state.config.pools = state.config.pools.filter(p => p.interface !== ifaceName);
  state.dirty = true;
  render();
  showToast('Пул удалён. Нажмите «Применить».', 'info');
}

// ── Toast ─────────────────────────────────────────────────────────────────────

let toastTimer;
function showToast(msg, type = 'info') {
  const t = document.getElementById('toast');
  t.textContent = msg;
  t.className = `toast ${type}`;
  t.classList.remove('hidden');
  clearTimeout(toastTimer);
  toastTimer = setTimeout(() => t.classList.add('hidden'), 3500);
}

// ── Event wiring ──────────────────────────────────────────────────────────────

document.getElementById('refreshBtn').addEventListener('click', loadAll);

document.getElementById('enableToggle').addEventListener('change', e => {
  state.config.enabled = e.target.checked;
  state.dirty = true;
  render();
});

document.getElementById('applyBtn').addEventListener('click', applyConfig);

// Delegated: edit/remove pool buttons + enabled checkboxes
document.getElementById('poolsGrid').addEventListener('click', e => {
  const editBtn   = e.target.closest('[data-edit]');
  const removeBtn = e.target.closest('[data-remove]');
  if (editBtn)   openPoolModal(editBtn.dataset.edit);
  if (removeBtn) removePool(removeBtn.dataset.remove);
});

document.getElementById('poolsGrid').addEventListener('change', e => {
  const chk = e.target.closest('.pool-enabled-chk');
  if (!chk) return;
  const ifaceName = chk.dataset.iface;
  const pool = poolForIface(ifaceName);
  if (pool) {
    pool.enabled = chk.checked;
    state.dirty = true;
    render();
  }
});

// Pool modal
document.getElementById('closePoolModal').addEventListener('click', closePoolModal);
document.getElementById('cancelPoolBtn').addEventListener('click', closePoolModal);
document.getElementById('poolModalBackdrop').addEventListener('click', closePoolModal);
document.getElementById('savePoolBtn').addEventListener('click', savePool);
document.getElementById('poolForm').addEventListener('submit', e => {
  e.preventDefault();
  savePool();
});
document.addEventListener('keydown', e => {
  if (e.key === 'Escape') closePoolModal();
});

// ── Init ──────────────────────────────────────────────────────────────────────

loadAll();
