(function optionsController() {
  'use strict';

  const ext = globalThis.OrbitOneVaultExtension;
  const browserApi = globalThis.browser || globalThis.chrome;
  const form = document.getElementById('settings-form');
  const tenantInput = document.getElementById('connection-profile-input');
  const baseUrlInput = document.getElementById('base-url-input');
  const apiTokenInput = document.getElementById('api-token-input');
  const autofillInput = document.getElementById('autofill-enabled-input');
  const savePromptInput = document.getElementById('save-prompt-enabled-input');
  const matchSubdomainsInput = document.getElementById('match-subdomains-input');
  const ignoredSites = document.getElementById('ignored-sites');
  const ignoredHostList = document.getElementById('ignored-host-list');
  const clearIgnoredHostsButton = document.getElementById('clear-ignored-hosts-button');
  const workspaceInput = document.getElementById('default-workspace-input');
  const vaultInput = document.getElementById('default-vault-input');
  const statusLine = document.getElementById('options-status-line');
  const connectionResult = document.getElementById('connection-result');
  const versionLabel = document.getElementById('extension-version-label');
  const updateStatusTitle = document.getElementById('update-status-title');
  const updateStatusCopy = document.getElementById('update-status-copy');
  const checkUpdatesButton = document.getElementById('check-updates-button');
  const downloadUpdateButton = document.getElementById('download-update-button');
  let settings = ext.normalizeSettings();
  let tenantDestinations = [];
  let activeContextId = '';

  function t(key, substitutions, fallback) {
    return ext.t(key, substitutions, fallback);
  }

  function renderIcons() {
    globalThis.lucide?.createIcons({
      attrs: {
        'aria-hidden': 'true',
        'stroke-width': 1.9,
      },
    });
  }

  function escapeHtml(value) {
    return String(value || '')
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#39;');
  }

  function setStatus(message, type = '') {
    statusLine.textContent = String(message || '');
    statusLine.className = `status-line${type ? ` ${type}` : ''}`;
  }

  function connection() {
    return settings.connections[0] || null;
  }

  function ensureConnection() {
    if (settings.connections.length) {
      return settings.connections[0];
    }
    const created = ext.normalizeConnection({
      id: ext.connectionId(),
      name: 'OrbitOne',
      baseUrl: '',
      apiToken: '',
    });
    settings.connections = [created];
    settings.activeConnectionId = created.id;
    return created;
  }

  function destinationByContextId(contextId = activeContextId) {
    return tenantDestinations.find((row) => row.connectionId === String(contextId || ''))
      || tenantDestinations[0]
      || null;
  }

  function selectedLocation(destination = destinationByContextId()) {
    return destination?.workspaces?.find((row) => Number(row.id) === Number(workspaceInput.value || 0))
      || null;
  }

  function collectForm() {
    const current = ensureConnection();
    current.baseUrl = String(baseUrlInput.value || '').trim();
    current.apiToken = String(apiTokenInput.value || '').trim();
    const destination = destinationByContextId();
    const tenantId = Number(destination?.tenantId || 0);
    const location = selectedLocation(destination);
    if (tenantId > 0 && location) {
      current.defaultsByTenant = current.defaultsByTenant || {};
      current.defaultsByTenant[String(tenantId)] = {
        scope: location.scope === 'workspace' ? 'workspace' : 'personal',
        workspaceId: Number(location.id || 0),
        vaultId: Number(vaultInput.value || 0),
      };
      destination.defaultScope = current.defaultsByTenant[String(tenantId)].scope;
      destination.defaultWorkspaceId = current.defaultsByTenant[String(tenantId)].workspaceId;
      destination.defaultVaultId = current.defaultsByTenant[String(tenantId)].vaultId;
      settings.activeTenantId = tenantId;
    }
    settings.activeConnectionId = current.id;
    settings.autofillEnabled = autofillInput.checked;
    settings.savePromptEnabled = savePromptInput.checked;
    settings.matchSubdomains = matchSubdomainsInput.checked;
  }

  function renderVaults(preferredId = 0) {
    const workspace = selectedLocation();
    const vaults = Array.isArray(workspace?.vaults) ? workspace.vaults : [];
    const selected = vaults.find((row) => Number(row.id) === Number(preferredId))
      || vaults.find((row) => row.isDefault)
      || vaults[0];
    vaultInput.innerHTML = [
      `<option value="0">${escapeHtml(t('defaultVault', undefined, 'Standard Vault'))}</option>`,
      ...vaults.map((vault) => `
        <option value="${Number(vault.id)}" ${Number(vault.id) === Number(selected?.id) ? 'selected' : ''}>${escapeHtml(vault.name)}</option>
      `),
    ].join('');
    vaultInput.value = String(Number(preferredId || selected?.id || 0));
  }

  function renderDestination(contextId = activeContextId) {
    const destination = destinationByContextId(contextId);
    if (!destination) {
      workspaceInput.innerHTML = `<option value="0">${escapeHtml(t('personalVault', undefined, 'Persönlicher Vault'))}</option>`;
      vaultInput.innerHTML = `<option value="0">${escapeHtml(t('defaultVault', undefined, 'Standard Vault'))}</option>`;
      return;
    }
    activeContextId = destination.connectionId;
    tenantInput.value = activeContextId;
    settings.activeTenantId = Number(destination.tenantId || 0);
    const workspaces = Array.isArray(destination.workspaces) ? destination.workspaces : [];
    const selected = workspaces.find((workspace) => (
      Number(workspace.id) === Number(destination.defaultWorkspaceId || 0)
      && workspace.scope === destination.defaultScope
    )) || workspaces[0];
    workspaceInput.innerHTML = workspaces.map((workspace) => `
      <option value="${Number(workspace.id)}" ${workspace === selected ? 'selected' : ''}>${escapeHtml(workspace.name)}</option>
    `).join('');
    renderVaults(destination.defaultVaultId || 0);
  }

  function renderDestinations(data) {
    tenantDestinations = Array.isArray(data?.connections) ? data.connections : [];
    const preferred = tenantDestinations.find((row) => (
      Number(row.tenantId) === Number(settings.activeTenantId || data?.activeTenantId || 0)
    )) || tenantDestinations[0];
    activeContextId = preferred?.connectionId || '';
    tenantInput.innerHTML = tenantDestinations.length
      ? tenantDestinations.map((destination) => `
        <option value="${escapeHtml(destination.connectionId)}">${escapeHtml(destination.tenant?.name || destination.connectionName)}</option>
      `).join('')
      : `<option value="">${escapeHtml(t('noTenantsLoaded', undefined, 'Noch keine Mandanten geladen'))}</option>`;
    renderDestination(activeContextId);

    const first = tenantDestinations[0];
    document.getElementById('connection-user').textContent = String(
      first?.user?.name || first?.user?.email || t('connected', undefined, 'Verbunden')
    );
    document.getElementById('connection-tenant').textContent = tenantDestinations.length
      ? t('tenantCount', [String(tenantDestinations.length)], `${tenantDestinations.length} Mandanten`)
      : '';
    connectionResult.hidden = !tenantDestinations.length;
  }

  function renderConnection() {
    const current = ensureConnection();
    baseUrlInput.value = current.baseUrl || '';
    apiTokenInput.value = current.apiToken || '';
    apiTokenInput.type = 'password';
    connectionResult.hidden = !tenantDestinations.length;
    if (tenantDestinations.length) {
      renderDestinations({ connections: tenantDestinations });
    } else {
      renderDestinations({ connections: [] });
    }
    renderIcons();
  }

  function renderIgnoredHosts() {
    const hosts = Array.isArray(settings.ignoredCredentialHosts)
      ? settings.ignoredCredentialHosts
      : [];
    ignoredSites.hidden = hosts.length === 0;
    ignoredHostList.innerHTML = hosts.map((host) => `
      <div class="ignored-host">
        <span title="${escapeHtml(host)}">${escapeHtml(host)}</span>
        <button class="icon-button" type="button" data-remove-ignored-host="${escapeHtml(host)}"
          title="${escapeHtml(t('allowWebsiteAgain', undefined, 'Website wieder zulassen'))}"
          aria-label="${escapeHtml(t('allowWebsiteAgain', undefined, 'Website wieder zulassen'))}">
          <i data-lucide="x"></i>
        </button>
      </div>
    `).join('');
    ignoredHostList.querySelectorAll('[data-remove-ignored-host]').forEach((button) => {
      button.addEventListener('click', async () => {
        collectForm();
        const host = String(button.getAttribute('data-remove-ignored-host') || '');
        settings.ignoredCredentialHosts = settings.ignoredCredentialHosts.filter((entry) => entry !== host);
        settings = await ext.saveSettings(settings);
        await ext.extension.runtime.sendMessage({ type: 'orbitone:settings-updated' }).catch(() => null);
        renderIgnoredHosts();
        setStatus(t('ignoredWebsiteRemoved', undefined, 'Die Website wird bei neuen Zugangsdaten wieder berücksichtigt.'), 'success');
      });
    });
    renderIcons();
  }

  function formatCheckedAt(value) {
    if (!value) {
      return t('notChecked', undefined, 'Noch nicht geprüft.');
    }
    const date = new Date(value);
    return Number.isNaN(date.getTime())
      ? t('lastChecked', undefined, 'Zuletzt geprüft.')
      : t('lastCheckedAt', [date.toLocaleString()], `Zuletzt geprüft: ${date.toLocaleString()}`);
  }

  function renderUpdateState(state = {}) {
    const installedVersion = String(state.installedVersion || browserApi?.runtime?.getManifest?.().version || '');
    versionLabel.textContent = t('versionLabel', [installedVersion], `Version ${installedVersion}`);
    if (state.error) {
      updateStatusTitle.textContent = t('updateCheckUnavailable', undefined, 'Updateprüfung vorübergehend nicht erreichbar');
      updateStatusCopy.textContent = `${state.error} ${formatCheckedAt(state.checkedAt)}`;
      downloadUpdateButton.hidden = true;
      return;
    }
    if (state.updateAvailable) {
      updateStatusTitle.textContent = t('versionAvailable', [state.latestVersion], `Version ${state.latestVersion} ist verfügbar`);
      updateStatusCopy.textContent = `${formatCheckedAt(state.checkedAt)} ${t('browserInstallsUpdates', undefined, 'Der Browser installiert native Updates automatisch.')}`;
      downloadUpdateButton.hidden = !state.downloadUrl;
      return;
    }
    updateStatusTitle.textContent = t('vaultIsCurrent', undefined, 'OrbitOne Vault ist aktuell');
    updateStatusCopy.textContent = formatCheckedAt(state.checkedAt);
    downloadUpdateButton.hidden = true;
  }

  async function loadUpdateState(force = false) {
    checkUpdatesButton.disabled = true;
    const response = await ext.extension.runtime.sendMessage({
      type: force ? 'orbitone:check-updates' : 'orbitone:get-update-state',
    });
    checkUpdatesButton.disabled = false;
    if (!response?.ok) {
      throw new Error(response?.error?.message || t('errorUpdateCheck', undefined, 'Updateprüfung fehlgeschlagen.'));
    }
    renderUpdateState(response.state);
  }

  async function saveSettings(showConfirmation = true) {
    collectForm();
    settings = await ext.saveSettings(settings);
    await ext.extension.runtime.sendMessage({ type: 'orbitone:settings-updated' }).catch(() => null);
    if (showConfirmation) {
      setStatus(t('settingsSaved', undefined, 'Einstellungen gespeichert.'), 'success');
    }
    return settings;
  }

  async function loadDestinations(force = false) {
    const current = connection();
    const response = await ext.extension.runtime.sendMessage({
      type: 'orbitone:get-destinations',
      connectionId: current?.id || '',
      includeAll: true,
      force,
    });
    if (!response?.ok || !response.connections?.length) {
      throw new Error(response?.error?.message || t('errorConnection', undefined, 'Verbindung fehlgeschlagen.'));
    }
    renderDestinations(response);
    return response;
  }

  async function testConnection() {
    setStatus(t('checkingConnection', undefined, 'Verbindung wird geprüft...'));
    await saveSettings(false);
    const current = connection();
    if (!current?.baseUrl || !current?.apiToken) {
      throw new Error(t('errorConnectionRequired', undefined, 'Adresse und Zugriffstoken sind erforderlich.'));
    }
    const response = await loadDestinations(true);
    const first = response.connections[0];
    current.tenantName = String(first?.tenant?.name || '');
    current.userName = String(first?.user?.name || first?.user?.email || '');
    try {
      current.name = new URL(current.baseUrl).hostname;
    } catch (_error) {
      current.name = 'OrbitOne';
    }
    settings = await ext.saveSettings(settings);
    setStatus(t(
      'tenantsConnected',
      [String(response.connections.length)],
      `${response.connections.length} Mandanten automatisch verbunden.`
    ), 'success');
  }

  async function boot() {
    ext.translateDocument();
    renderIcons();
    renderUpdateState({ installedVersion: browserApi?.runtime?.getManifest?.().version || '' });
    settings = await ext.getSettings();
    ensureConnection();
    autofillInput.checked = settings.autofillEnabled !== false;
    savePromptInput.checked = settings.savePromptEnabled !== false;
    matchSubdomainsInput.checked = settings.matchSubdomains === true;
    renderIgnoredHosts();
    renderConnection();
    if (ext.isConfigured(settings)) {
      await loadDestinations(false);
    }
    await loadUpdateState(false).catch(() => null);
  }

  form?.addEventListener('submit', async (event) => {
    event.preventDefault();
    try {
      await saveSettings();
    } catch (error) {
      setStatus(error?.message || t('errorSettingsSave', undefined, 'Einstellungen konnten nicht gespeichert werden.'), 'error');
    }
  });

  tenantInput?.addEventListener('change', () => {
    collectForm();
    activeContextId = String(tenantInput.value || '');
    renderDestination(activeContextId);
    setStatus('');
  });

  document.getElementById('test-connection-button')?.addEventListener('click', () => {
    testConnection().catch((error) => setStatus(error?.message || t('errorConnection', undefined, 'Verbindung fehlgeschlagen.'), 'error'));
  });

  document.getElementById('toggle-token-button')?.addEventListener('click', () => {
    apiTokenInput.type = apiTokenInput.type === 'password' ? 'text' : 'password';
    document.getElementById('toggle-token-button').innerHTML = apiTokenInput.type === 'password'
      ? '<i data-lucide="eye"></i>'
      : '<i data-lucide="eye-off"></i>';
    renderIcons();
  });

  checkUpdatesButton?.addEventListener('click', () => {
    loadUpdateState(true).catch((error) => {
      checkUpdatesButton.disabled = false;
      renderUpdateState({
        installedVersion: browserApi?.runtime?.getManifest?.().version || '',
        checkedAt: new Date().toISOString(),
        error: error?.message || t('errorUpdateCheck', undefined, 'Updateprüfung fehlgeschlagen.'),
      });
    });
  });

  downloadUpdateButton?.addEventListener('click', () => {
    ext.extension.runtime.sendMessage({ type: 'orbitone:open-update' }).catch(() => null);
  });

  workspaceInput?.addEventListener('change', () => renderVaults());

  clearIgnoredHostsButton?.addEventListener('click', async () => {
    collectForm();
    settings.ignoredCredentialHosts = [];
    settings = await ext.saveSettings(settings);
    await ext.extension.runtime.sendMessage({ type: 'orbitone:settings-updated' }).catch(() => null);
    renderIgnoredHosts();
    setStatus(t('ignoredWebsitesCleared', undefined, 'Alle Websites werden wieder berücksichtigt.'), 'success');
  });

  boot().catch((error) => setStatus(
    error?.message || t('errorSettingsLoad', undefined, 'Einstellungen konnten nicht geladen werden.'),
    'error'
  ));
}());
