import { renderHeader } from '../components/header.js';
import { saveEntrySettings, state } from '../state.js';
import { checkServerAvailabilityByKey } from '../services/server-health-service.js';

export const pageMeta = { id: 'server-settings-view', title: 'Настройки серверов' };

const SERVER_FIELDS = [
  { key: 'solanaServer', label: 'Адрес Solana сервера' },
  { key: 'shineServer', label: 'Адрес сервера Сияние' },
  { key: 'arweaveServer', label: 'Адрес сервера Arweave' },
];

export function render({ navigate }) {
  const screen = document.createElement('section');
  screen.className = 'stack';

  const draft = {
    language: state.entrySettings.language,
    solanaServer: state.entrySettings.solanaServer,
    shineServer: state.entrySettings.shineServer,
    arweaveServer: state.entrySettings.arweaveServer,
    callPreflightTimeoutMs: Number(state.entrySettings.callPreflightTimeoutMs || 6000),
    statuses: { ...state.entrySettings.statuses },
  };

  const timers = new Map();

  const body = document.createElement('div');
  body.className = 'card stack';

  SERVER_FIELDS.forEach((field) => {
    const block = document.createElement('div');
    block.className = 'stack';

    const title = document.createElement('label');
    title.className = 'field-label';
    title.textContent = field.label;

    const input = document.createElement('input');
    input.className = 'input';
    input.type = 'text';
    input.value = draft[field.key];

    const controls = document.createElement('div');
    controls.className = 'row wrap-row';

    const checkButton = document.createElement('button');
    checkButton.className = 'ghost-btn server-check-btn';
    checkButton.type = 'button';
    checkButton.textContent = 'Проверить';

    const status = document.createElement('span');
    status.className = 'status-line';

    const applyStatus = (value) => {
      draft.statuses[field.key] = value;
      checkButton.classList.remove('is-available', 'is-unavailable');
      status.classList.remove('is-available', 'is-unavailable');

      if (value === 'available') {
        status.textContent = 'Доступен';
        checkButton.classList.add('is-available');
        status.classList.add('is-available');
      } else if (value === 'unavailable') {
        status.textContent = 'Недоступен';
        checkButton.classList.add('is-unavailable');
        status.classList.add('is-unavailable');
      } else {
        status.textContent = 'Статус не проверен';
      }
    };

    const runCheck = async () => {
      draft[field.key] = input.value.trim();
      checkButton.disabled = true;
      checkButton.textContent = 'Проверка...';
      try {
        const next = await checkServerAvailabilityByKey(field.key, input.value);
        applyStatus(next);
      } finally {
        checkButton.disabled = false;
        checkButton.textContent = 'Проверить';
      }
    };

    applyStatus(draft.statuses[field.key]);

    checkButton.addEventListener('click', runCheck);
    input.addEventListener('input', () => {
      draft[field.key] = input.value;
      applyStatus('idle');
      window.clearTimeout(timers.get(field.key));
      timers.set(field.key, window.setTimeout(() => {
        void runCheck();
      }, 3000));
    });
    input.addEventListener('blur', () => {
      void runCheck();
    });
    input.addEventListener('keydown', (event) => {
      if (event.key === 'Enter') {
        event.preventDefault();
        void runCheck();
      }
    });

    controls.append(checkButton, status);
    block.append(title, input, controls);
    body.append(block);
  });

  const callSettings = document.createElement('div');
  callSettings.className = 'stack';

  const callTimeoutLabel = document.createElement('label');
  callTimeoutLabel.className = 'field-label';
  callTimeoutLabel.textContent = 'Таймаут пред-подключения перед звонком (мс)';

  const callTimeoutInput = document.createElement('input');
  callTimeoutInput.className = 'input';
  callTimeoutInput.type = 'number';
  callTimeoutInput.min = '1000';
  callTimeoutInput.max = '20000';
  callTimeoutInput.step = '500';
  callTimeoutInput.value = String(Math.max(1000, Math.min(20000, Number(draft.callPreflightTimeoutMs) || 6000)));
  callTimeoutInput.addEventListener('input', () => {
    const n = Number(callTimeoutInput.value);
    if (!Number.isFinite(n)) return;
    draft.callPreflightTimeoutMs = Math.max(1000, Math.min(20000, Math.round(n)));
  });

  const callTimeoutHint = document.createElement('p');
  callTimeoutHint.className = 'meta-muted';
  callTimeoutHint.textContent = 'Перед исходящим звонком клиент проверяет и восстанавливает WS-сессию. Это время ожидания такой проверки перед ошибкой «Сервер временно недоступен».';

  callSettings.append(callTimeoutLabel, callTimeoutInput, callTimeoutHint);
  body.append(callSettings);

  const actions = document.createElement('div');
  actions.className = 'auth-footer-actions';

  const cancelButton = document.createElement('button');
  cancelButton.className = 'ghost-btn';
  cancelButton.type = 'button';
  cancelButton.textContent = 'Отмена';
  cancelButton.addEventListener('click', () => navigate('settings-view'));

  const saveButton = document.createElement('button');
  saveButton.className = 'primary-btn';
  saveButton.type = 'button';
  saveButton.textContent = 'Сохранить';
  saveButton.addEventListener('click', () => {
    saveEntrySettings(draft);
    navigate('settings-view');
  });

  actions.append(cancelButton, saveButton);

  const help = document.createElement('button');
  help.className = 'help-fab';
  help.type = 'button';
  help.textContent = '?';
  help.addEventListener('click', () => {
    window.alert(
      'Текст для разработчиков: после ввода адреса любого сервера автопроверка запускается по кнопке "Проверить", после перехода в другое поле или если подождать больше 3 секунд. Зелёный статус означает доступность, красный — недоступность.',
    );
  });

  screen.append(
    renderHeader({
      title: 'Настройки серверов',
      leftAction: { label: '←', onClick: () => navigate('settings-view') },
    }),
    body,
    actions,
    help,
  );

  screen.cleanup = () => {
    timers.forEach((timerId) => window.clearTimeout(timerId));
  };

  return screen;
}
