import { renderHeader } from '../components/header.js';
import { addAppLogEntry, authService, state } from '../state.js';
import {
  isClientErrorReportingEnabled,
  setClientErrorReportingEnabled,
} from '../services/client-error-reporter.js';
import {
  canInstallPwa,
  isStandalonePwaMode,
  onPwaInstallAvailabilityChange,
  promptPwaInstall,
} from '../services/pwa-install-service.js';
import { initPwaPush } from '../services/pwa-push-service.js';
import { getArweaveWalletFromStoredDeviceKey } from '../services/arweave-wallet-service.js';
import {
  prepareAvatarImageFile,
  uploadArweaveFile,
  validateAvatarSourceFile,
} from '../services/arweave-file-service.js';

export const pageMeta = { id: 'developer-settings-view', title: 'Настройки разработчика' };

function clearArweaveJwk(walletCtx) {
  if (!walletCtx?.jwk || typeof walletCtx.jwk !== 'object') return;
  Object.keys(walletCtx.jwk).forEach((key) => {
    walletCtx.jwk[key] = '';
  });
  walletCtx.jwk = null;
}

function formatBytes(bytes) {
  const value = Number(bytes || 0);
  if (!Number.isFinite(value) || value <= 0) return '0 B';
  if (value < 1024) return `${value} B`;
  if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)} KB`;
  return `${(value / (1024 * 1024)).toFixed(2)} MB`;
}

function openDeveloperAvatarUploadModal({ walletLogin, storagePwd, gateway } = {}) {
  const root = document.getElementById('modal-root');
  if (!root) return;

  root.innerHTML = `
    <div class="modal" id="settings-dev-avatar-modal">
      <div class="modal-card stack settings-dev-avatar-modal-card">
        <h3 class="modal-title">Загрузить аватар (Arweave)</h3>
        <label class="field-label" for="settings-dev-avatar-login">Логин пользователя</label>
        <input class="input" id="settings-dev-avatar-login" type="text" maxlength="60" placeholder="Например: aidar" value="" />
        <label class="field-label" for="settings-dev-avatar-file">Файл изображения</label>
        <input class="input" id="settings-dev-avatar-file" type="file" accept="image/jpeg,image/png,image/webp" />
        <p class="meta-muted">Поддерживаются JPEG, PNG, WebP. Перед загрузкой изображение будет оптимизировано.</p>
        <div class="settings-dev-avatar-meta" id="settings-dev-avatar-meta"></div>
        <p class="inline-error settings-dev-avatar-error" id="settings-dev-avatar-error"></p>
        <div class="form-actions-grid">
          <button class="secondary-btn" id="settings-dev-avatar-cancel" type="button">Закрыть</button>
          <button class="primary-btn" id="settings-dev-avatar-upload" type="button">Загрузить</button>
        </div>
        <div class="card stack settings-dev-avatar-result" id="settings-dev-avatar-result" hidden>
          <p class="meta-muted">Transaction ID:</p>
          <p class="key-value" id="settings-dev-avatar-txid"></p>
          <button class="ghost-btn" id="settings-dev-avatar-copy" type="button">Скопировать TX ID</button>
        </div>
      </div>
    </div>
  `;

  const modal = root.querySelector('#settings-dev-avatar-modal');
  const loginInput = root.querySelector('#settings-dev-avatar-login');
  const fileInput = root.querySelector('#settings-dev-avatar-file');
  const metaEl = root.querySelector('#settings-dev-avatar-meta');
  const errorEl = root.querySelector('#settings-dev-avatar-error');
  const cancelBtn = root.querySelector('#settings-dev-avatar-cancel');
  const uploadBtn = root.querySelector('#settings-dev-avatar-upload');
  const resultCard = root.querySelector('#settings-dev-avatar-result');
  const txidEl = root.querySelector('#settings-dev-avatar-txid');
  const copyBtn = root.querySelector('#settings-dev-avatar-copy');

  if (loginInput instanceof HTMLInputElement) {
    loginInput.value = String(walletLogin || '').trim();
  }

  let isClosed = false;
  const closeModal = () => {
    if (isClosed) return;
    isClosed = true;
    root.innerHTML = '';
  };

  const setError = (text) => {
    if (errorEl) errorEl.textContent = String(text || '');
  };
  const setMeta = (text) => {
    if (metaEl) metaEl.textContent = String(text || '');
  };
  const setTxId = (txId) => {
    if (!(resultCard instanceof HTMLElement) || !(txidEl instanceof HTMLElement)) return;
    const value = String(txId || '').trim();
    txidEl.textContent = value;
    resultCard.hidden = !value;
  };

  modal?.addEventListener('click', (event) => {
    if (event.target === modal) closeModal();
  });
  cancelBtn?.addEventListener('click', closeModal);
  copyBtn?.addEventListener('click', async () => {
    const txId = String(txidEl?.textContent || '').trim();
    if (!txId) return;
    try {
      await navigator.clipboard.writeText(txId);
      setError('');
    } catch {
      setError('Не удалось скопировать TX ID.');
    }
  });

  uploadBtn?.addEventListener('click', async () => {
    setError('');
    setTxId('');
    const targetLogin = String(loginInput?.value || '').trim();
    const file = fileInput?.files?.[0] || null;
    if (!targetLogin) {
      setError('Введите логин пользователя.');
      return;
    }
    if (!file) {
      setError('Выберите файл изображения.');
      return;
    }
    if (!String(walletLogin || '').trim() || !String(storagePwd || '').trim()) {
      setError('Нет активной сессии. Войдите заново и повторите.');
      return;
    }

    uploadBtn.disabled = true;
    let walletCtx = null;
    try {
      validateAvatarSourceFile(file);
      setMeta('Подготовка изображения...');
      const optimized = await prepareAvatarImageFile(file);
      setMeta(
        `Файл подготовлен: ${formatBytes(optimized.originalSizeBytes)} → ${formatBytes(optimized.optimizedSizeBytes)} `
        + `(${optimized.width}x${optimized.height}, ${optimized.contentType})`,
      );

      walletCtx = await getArweaveWalletFromStoredDeviceKey({
        login: walletLogin,
        storagePwd,
        onStatus: (message) => setMeta(message),
      });
      setMeta('Загрузка в Arweave...');

      const uploaded = await uploadArweaveFile({
        gateway,
        jwk: walletCtx?.jwk,
        file: optimized.file,
        tags: [
          { name: 'SHiNE-Profile-Login', value: targetLogin },
        ],
      });
      const txId = String(uploaded?.id || '').trim();
      if (!txId) throw new Error('Пустой Transaction ID');

      setMeta('Загрузка завершена.');
      setTxId(txId);
    } catch (error) {
      const message = String(error?.message || '');
      if (
        message === 'Выберите файл изображения.'
        || message === 'Поддерживаются только JPEG, PNG или WebP.'
        || message === 'Файл слишком большой. Максимум 10 MB.'
        || message === 'Не удалось подготовить изображение.'
      ) {
        setError(message);
      } else {
        setError('Не удалось загрузить аватар в Arweave.');
      }
    } finally {
      clearArweaveJwk(walletCtx);
      uploadBtn.disabled = false;
    }
  });
}

async function forceUiUpdateNow() {
  try {
    window.history.replaceState({}, '', '/settings-view');
    window.dispatchEvent(new PopStateEvent('popstate'));
  } catch {}
  if (!('serviceWorker' in navigator)) {
    window.location.reload();
    return;
  }
  try {
    const registrations = await navigator.serviceWorker.getRegistrations();
    await Promise.all(registrations.map(async (registration) => {
      try { await registration.update(); } catch {}
      if (registration.waiting) {
        try { registration.waiting.postMessage({ type: 'SKIP_WAITING' }); } catch {}
      }
    }));
  } catch {}
  window.setTimeout(() => window.location.reload(), 450);
}

function showClientUpdateHelp() {
  window.alert(
    'Если UI не обновился:\n\n'
    + '1) Закройте вкладки с SHiNE.\n'
    + '2) Откройте chrome://settings/siteData и удалите данные для shineup.me.\n'
    + '3) Если приложение установлено как PWA — удалите его с устройства.\n'
    + '4) Откройте https://shineup.me заново и выполните вход.\n'
    + '5) Если всё ещё старая версия — откройте в режиме инкогнито и проверьте версию в Настройки -> Версии.'
  );
}

function openUiErrorReportingModal() {
  const root = document.getElementById('modal-root');
  if (!root) return;

  const enabled = isClientErrorReportingEnabled();
  root.innerHTML = `
    <div class="modal" id="settings-ui-error-reporting-modal">
      <div class="modal-card stack">
        <h3 class="modal-title">Отправка UI-ошибок на сервер</h3>
        <p class="meta-muted">Для разработчиков: при включении ошибки интерфейса будут автоматически отправляться на сервер для диагностики.</p>
        <label class="row wrap-row" for="ui-error-reporting-toggle">
          <input id="ui-error-reporting-toggle" type="checkbox" ${enabled ? 'checked' : ''} />
          <span>Отправлять ошибки на сервер</span>
        </label>
        <div class="form-actions-grid">
          <button class="secondary-btn" id="ui-error-reporting-cancel" type="button">Отмена</button>
          <button class="primary-btn" id="ui-error-reporting-save" type="button">Сохранить</button>
        </div>
      </div>
    </div>
  `;

  const close = () => { root.innerHTML = ''; };
  root.querySelector('#ui-error-reporting-cancel')?.addEventListener('click', close);
  root.querySelector('#ui-error-reporting-save')?.addEventListener('click', () => {
    const checked = root.querySelector('#ui-error-reporting-toggle')?.checked === true;
    setClientErrorReportingEnabled(checked);
    close();
  });
}

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

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

  const card = document.createElement('div');
  card.className = 'card stack settings-developer-card';
  card.innerHTML = `
    <button class="text-btn" type="button" id="settings-force-ui-update">Принудительно обновить UI</button>
    <button class="text-btn" type="button" id="settings-force-update-help">Клиент не обновляется?</button>
    <button class="text-btn" type="button" id="settings-ui-error-reporting">Отправлять ошибки на сервер</button>
    <button class="text-btn" type="button" id="settings-solana-users-init">Solana: init регистрации</button>
    <button class="text-btn" type="button" id="settings-app-log">Лог приложения</button>
    <button class="text-btn" type="button" id="settings-pwa-diagnostics">Диагностика PWA / Push</button>
    <button class="text-btn" type="button" id="settings-pwa-install">Как установить PWA</button>
    <button class="text-btn" type="button" id="settings-upload-avatar">Загрузить аватар</button>
  `;

  const appLogBtn = card.querySelector('#settings-app-log');
  const diagnosticsBtn = card.querySelector('#settings-pwa-diagnostics');
  const pwaInstallBtn = card.querySelector('#settings-pwa-install');
  const uploadAvatarBtn = card.querySelector('#settings-upload-avatar');
  const forceUpdateBtn = card.querySelector('#settings-force-ui-update');
  const forceUpdateHelpBtn = card.querySelector('#settings-force-update-help');
  const uiErrorReportingBtn = card.querySelector('#settings-ui-error-reporting');
  const solanaUsersInitBtn = card.querySelector('#settings-solana-users-init');

  appLogBtn?.addEventListener('click', () => navigate('app-log-view'));
  solanaUsersInitBtn?.addEventListener('click', () => navigate('solana-users-init-view'));
  diagnosticsBtn?.addEventListener('click', () => navigate('pwa-diagnostics-view'));
  uploadAvatarBtn?.addEventListener('click', () => {
    openDeveloperAvatarUploadModal({
      walletLogin: state.session.login,
      storagePwd: state.session.storagePwdInMemory,
      gateway: state.entrySettings.arweaveServer,
    });
  });
  forceUpdateHelpBtn?.addEventListener('click', showClientUpdateHelp);
  uiErrorReportingBtn?.addEventListener('click', openUiErrorReportingModal);

  forceUpdateBtn?.addEventListener('click', async () => {
    forceUpdateBtn.disabled = true;
    try {
      addAppLogEntry({
        level: 'info',
        source: 'ui-update',
        message: 'Пользователь запросил принудительное обновление UI',
      });
      await forceUiUpdateNow();
    } finally {
      forceUpdateBtn.disabled = false;
    }
  });

  const syncPwaButtonLabel = () => {
    if (isStandalonePwaMode()) {
      pwaInstallBtn.textContent = 'PWA установлено (проверить WebPush)';
      return;
    }
    if (canInstallPwa()) {
      pwaInstallBtn.textContent = 'Зарегистрировать PWA';
      return;
    }
    pwaInstallBtn.textContent = 'Как установить PWA';
  };

  const unsubscribeInstallAvailability = onPwaInstallAvailabilityChange(() => {
    syncPwaButtonLabel();
  });
  syncPwaButtonLabel();

  pwaInstallBtn.addEventListener('click', async () => {
    pwaInstallBtn.disabled = true;
    try {
      await initPwaPush({
        authService,
        onLog: (entry) => addAppLogEntry(entry),
      });

      if (canInstallPwa()) {
        const result = await promptPwaInstall();
        const accepted = result.outcome === 'accepted';
        addAppLogEntry({
          level: 'info',
          source: 'pwa-install',
          message: accepted ? 'Пользователь принял установку PWA' : 'Пользователь отклонил установку PWA',
          details: { outcome: result.outcome || 'unknown' },
        });
        if (accepted) {
          window.alert('Установка PWA подтверждена. Проверьте приложение на главном экране устройства.');
        }
      } else if (!isStandalonePwaMode()) {
        window.alert('Для установки откройте меню браузера и выберите "Установить приложение" или "Добавить на главный экран".');
      } else {
        window.alert('PWA уже установлено. WebPush перерегистрирован.');
      }
    } catch (error) {
      addAppLogEntry({
        level: 'warn',
        source: 'pwa-install',
        message: 'Не удалось зарегистрировать PWA/WebPush',
        details: { error: error?.message || 'unknown' },
      });
      window.alert(`Ошибка регистрации PWA: ${error?.message || 'unknown'}`);
    } finally {
      pwaInstallBtn.disabled = false;
      syncPwaButtonLabel();
    }
  });

  screen.cleanup = () => {
    unsubscribeInstallAvailability();
  };
  screen.append(card);
  return screen;
}
