import { sendMessage, escapeHtml, openVaultTab } from '../../shared/state';
import type { VaultSettings, DeviceSettings, TrashRetention, HistoryRetention } from '../../shared/types';
import type { ColorScheme } from '../../shared/color-scheme';
import {
  loadColorScheme, saveColorScheme, resetColorScheme,
  DEFAULT_DIGIT_COLOR, DEFAULT_SYMBOL_COLOR,
} from '../../shared/color-scheme';
import { colorizePassword } from '../../shared/password-coloring';
import { openGeneratorPanel, closeGeneratorPanel, isGeneratorPanelOpen } from './generator-panel';
import { renderSecuritySection, teardownSecuritySection } from './settings-security';

type SettingsSection =
  | 'autofill'
  | 'display'
  | 'security'
  | 'generator'
  | 'retention'
  | 'backup'
  | 'import';

const NAV_ITEMS: Array<{ id: SettingsSection; icon: string; label: string; group: 'device' | 'vault' }> = [
  { id: 'autofill',  icon: '⊙', label: 'Autofill',   group: 'device' },
  { id: 'display',   icon: '◈', label: 'Display',    group: 'device' },
  { id: 'security',  icon: '◉', label: 'Security',   group: 'vault'  },
  { id: 'generator', icon: '↻', label: 'Generator',  group: 'vault'  },
  { id: 'retention', icon: '▦', label: 'Retention',  group: 'vault'  },
  { id: 'backup',    icon: '⤓', label: 'Backup',     group: 'vault'  },
  { id: 'import',    icon: '≡', label: 'Import',     group: 'vault'  },
];

let activeSection: SettingsSection = 'autofill';
let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null;
let pendingVaultSettings: VaultSettings | null = null;
let sessionHandle: number | null = null;

export async function renderSettings(container: HTMLElement): Promise<void> {
  container.innerHTML = `
    <div class="settings-layout">
      <nav class="settings-nav" id="settings-nav">
        <div class="settings-nav__group-label">Device</div>
        ${NAV_ITEMS.filter(n => n.group === 'device').map(navItemHtml).join('')}
        <div class="settings-nav__group-label">Vault</div>
        ${NAV_ITEMS.filter(n => n.group === 'vault').map(navItemHtml).join('')}
      </nav>
      <div class="settings-content" id="settings-content"></div>
    </div>
  `;

  const unlockedResp = await sendMessage({ type: 'is_unlocked' });
  sessionHandle = (unlockedResp.ok && unlockedResp.data && (unlockedResp.data as { unlocked: boolean }).unlocked) ? 1 : null;

  wireNav();
  await renderSection(activeSection);
}

/**
 * Common cleanup invoked by both the device-settings teardown
 * (settings.ts) and the vault-settings teardown (settings-vault.ts).
 * Centralized to avoid the "regression class with known prior leaks"
 * DEV-C P2 flagged.
 *
 * Closes the generator popover and detaches the supplied keydown
 * handler from the document if present. Returns the new handler value
 * (always null), so the caller can do `handler = teardownSettingsCommon(handler)`.
 */
export function teardownSettingsCommon(
  keyHandler: ((e: KeyboardEvent) => void) | null,
): null {
  closeGeneratorPanel();
  if (keyHandler) {
    document.removeEventListener('keydown', keyHandler);
  }
  return null;
}

export function teardownSettings(): void {
  activeKeyHandler = teardownSettingsCommon(activeKeyHandler);
  teardownSecuritySection();
  pendingVaultSettings = null;
  sessionHandle = null;
}

function navItemHtml(item: (typeof NAV_ITEMS)[0]): string {
  const active = item.id === activeSection ? ' settings-nav__item--active' : '';
  return `
    <button class="settings-nav__item${active}" data-section="${item.id}">
      <span class="settings-nav__icon" aria-hidden="true">${item.icon}</span>
      <span class="settings-nav__label">${escapeHtml(item.label)}</span>
    </button>
  `;
}

function wireNav(): void {
  document.getElementById('settings-nav')?.querySelectorAll<HTMLButtonElement>('[data-section]')
    .forEach((btn) => {
      btn.addEventListener('click', async () => {
        teardownSecuritySection();
        closeGeneratorPanel();
        activeSection = btn.dataset.section as SettingsSection;
        document.querySelectorAll('.settings-nav__item').forEach(b => b.classList.remove('settings-nav__item--active'));
        btn.classList.add('settings-nav__item--active');
        await renderSection(activeSection);
      });
    });
}

async function renderSection(section: SettingsSection): Promise<void> {
  const content = document.getElementById('settings-content');
  if (!content) return;

  switch (section) {
    case 'autofill':  return renderAutofillSection(content);
    case 'display':   return renderDisplaySection(content);
    case 'security':  return renderSecuritySection(content, sessionHandle);
    case 'generator': return renderGeneratorSection(content);
    case 'retention': return renderRetentionSection(content);
    case 'backup':    return renderBackupSection(content);
    case 'import':    return renderImportSection(content);
  }
}

// --- Section stubs (filled in by Tasks 3-9) ---

async function renderAutofillSection(content: HTMLElement): Promise<void> {
  const [settingsResp, blacklistResp] = await Promise.all([
    sendMessage({ type: 'get_settings' }),
    sendMessage({ type: 'get_blacklist' }),
  ]);

  const settings: DeviceSettings = settingsResp.ok
    ? (settingsResp.data as { settings: DeviceSettings }).settings
    : { captureEnabled: false, captureStyle: 'bar' };

  const blacklist: string[] = blacklistResp.ok
    ? (blacklistResp.data as { blacklist: string[] }).blacklist
    : [];

  content.innerHTML = `
    <h3 class="settings-section-title">Capture</h3>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Auto-detect logins</div>
        <div class="setting-row__desc">Show a prompt when a login form is detected.</div>
      </div>
      <div class="setting-row__control">
        <input type="checkbox" id="capture-enabled" ${settings.captureEnabled ? 'checked' : ''}>
      </div>
    </div>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Prompt style</div>
        <div class="setting-row__desc">How to prompt when a login is detected.</div>
      </div>
      <div class="setting-row__control" style="display:flex; gap:6px;">
        <button class="btn ${settings.captureStyle === 'bar'   ? 'btn-active' : ''}" id="style-bar"   style="font-size:11px;">bar</button>
        <button class="btn ${settings.captureStyle === 'toast' ? 'btn-active' : ''}" id="style-toast" style="font-size:11px;">toast</button>
      </div>
    </div>

    <h3 class="settings-section-title" style="margin-top:20px;">Blocked sites</h3>
    <div id="blacklist-container">
      ${blacklist.length > 0
        ? blacklist.map((h) => `
          <div class="setting-row">
            <div class="setting-row__info">
              <div class="setting-row__title">${escapeHtml(h)}</div>
            </div>
            <button class="btn remove-bl" data-hostname="${escapeHtml(h)}" style="font-size:11px;">remove</button>
          </div>
        `).join('')
        : '<p class="muted" style="font-size:12px; padding:8px 0;">No blocked sites.</p>'}
    </div>
  `;

  document.getElementById('capture-enabled')?.addEventListener('change', async (e) => {
    const enabled = (e.target as HTMLInputElement).checked;
    await sendMessage({ type: 'update_settings', settings: { captureEnabled: enabled } });
  });

  document.getElementById('style-bar')?.addEventListener('click', async () => {
    await sendMessage({ type: 'update_settings', settings: { captureStyle: 'bar' } });
    renderAutofillSection(content);
  });

  document.getElementById('style-toast')?.addEventListener('click', async () => {
    await sendMessage({ type: 'update_settings', settings: { captureStyle: 'toast' } });
    renderAutofillSection(content);
  });

  content.querySelectorAll<HTMLButtonElement>('.remove-bl').forEach((btn) => {
    btn.addEventListener('click', async () => {
      const host = btn.dataset.hostname;
      if (!host) return;
      await sendMessage({ type: 'remove_blacklist', hostname: host });
      renderAutofillSection(content);
    });
  });
}

async function renderDisplaySection(content: HTMLElement): Promise<void> {
  const scheme = await loadColorScheme();

  content.innerHTML = `
    <h3 class="settings-section-title">Password coloring</h3>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Digit color</div>
      </div>
      <div class="setting-row__control">
        <input type="color" id="digit-color" value="${escapeHtml(scheme.digit_color)}">
      </div>
    </div>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Symbol color</div>
      </div>
      <div class="setting-row__control">
        <input type="color" id="symbol-color" value="${escapeHtml(scheme.symbol_color)}">
      </div>
    </div>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Preview</div>
      </div>
      <div class="setting-row__control">
        <span id="color-preview" style="font-family:monospace; font-size:13px;"></span>
      </div>
    </div>
    <div style="margin-top:12px;">
      <button class="btn" id="reset-colors" style="font-size:11px;">Reset defaults</button>
    </div>
  `;

  function refreshPreview(s: ColorScheme): void {
    const preview = document.getElementById('color-preview');
    if (!preview) return;
    preview.style.setProperty('--relicario-pwd-digit-color', s.digit_color);
    preview.style.setProperty('--relicario-pwd-symbol-color', s.symbol_color);
    preview.innerHTML = '';
    preview.appendChild(colorizePassword('Abc123!@#'));
  }

  refreshPreview(scheme);

  document.getElementById('digit-color')?.addEventListener('change', async (e) => {
    const color = (e.target as HTMLInputElement).value;
    const current = await loadColorScheme();
    await saveColorScheme({ ...current, digit_color: color });
    refreshPreview({ ...current, digit_color: color });
  });

  document.getElementById('symbol-color')?.addEventListener('change', async (e) => {
    const color = (e.target as HTMLInputElement).value;
    const current = await loadColorScheme();
    await saveColorScheme({ ...current, symbol_color: color });
    refreshPreview({ ...current, symbol_color: color });
  });

  document.getElementById('reset-colors')?.addEventListener('click', async () => {
    await resetColorScheme();
    renderDisplaySection(content);
  });
}

async function renderGeneratorSection(content: HTMLElement): Promise<void> {
  content.innerHTML = '<p class="muted" style="padding:20px;font-size:12px;">Loading…</p>';
  const resp = await sendMessage({ type: 'get_vault_settings' });
  if (!resp.ok) {
    const errorMsg = (resp as { ok: false; error: string }).error;
    content.innerHTML = `<p class="muted" style="padding:20px;">Failed to load: ${escapeHtml(errorMsg)}</p>`;
    return;
  }
  const settings = (resp.data as { settings: VaultSettings }).settings;

  content.innerHTML = `
    <h3 class="settings-section-title">Generator defaults</h3>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Configure generator</div>
        <div class="setting-row__desc">Password length, character classes, passphrase word count.</div>
      </div>
      <div class="setting-row__control">
        <button class="btn" id="open-generator-panel" style="font-size:11px;">Configure ▸</button>
      </div>
    </div>
  `;

  document.getElementById('open-generator-panel')?.addEventListener('click', (e) => {
    const trigger = e.currentTarget as HTMLElement;
    if (isGeneratorPanelOpen()) {
      closeGeneratorPanel();
      return;
    }
    openGeneratorPanel({
      parent: content,
      trigger,
      initial: settings.generator_defaults,
      context: 'configure-defaults',
    });
  });
}

async function renderRetentionSection(content: HTMLElement): Promise<void> {
  content.innerHTML = '<p class="muted" style="padding:20px;font-size:12px;">Loading…</p>';
  const resp = await sendMessage({ type: 'get_vault_settings' });
  if (!resp.ok) {
    content.innerHTML = `<p class="muted" style="padding:20px;">Failed to load: ${escapeHtml(resp.error ?? 'unknown')}</p>`;
    return;
  }
  const settings = (resp.data as { settings: VaultSettings }).settings;
  pendingVaultSettings = { ...settings };

  content.innerHTML = `
    <h3 class="settings-section-title">Trash retention</h3>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Keep deleted items for</div>
        <div class="setting-row__desc">Items in trash older than this are permanently deleted on the next sync.</div>
      </div>
      <div class="setting-row__control">
        <select id="trash-retention" style="font-size:12px;">
          <option value="days:7">7 days</option>
          <option value="days:30">30 days</option>
          <option value="days:90">90 days</option>
          <option value="forever">Forever</option>
        </select>
      </div>
    </div>

    <h3 class="settings-section-title" style="margin-top:20px;">Field history retention</h3>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Keep password history for</div>
        <div class="setting-row__desc">History entries older than this are pruned on save.</div>
      </div>
      <div class="setting-row__control">
        <select id="history-retention" style="font-size:12px;">
          <option value="last_n:5">Last 5</option>
          <option value="last_n:10">Last 10</option>
          <option value="days:90">90 days</option>
          <option value="days:365">1 year</option>
          <option value="forever">Forever</option>
        </select>
      </div>
    </div>
    <div style="margin-top:12px;">
      <button class="btn btn-primary" id="save-retention" style="font-size:11px;">Save retention settings</button>
    </div>
  `;

  // Set current select values
  (document.getElementById('trash-retention') as HTMLSelectElement).value =
    trashRetentionToValue(settings.trash_retention);
  (document.getElementById('history-retention') as HTMLSelectElement).value =
    historyRetentionToValue(settings.field_history_retention);

  document.getElementById('trash-retention')?.addEventListener('change', (e) => {
    if (pendingVaultSettings) {
      pendingVaultSettings.trash_retention = valueToTrashRetention((e.target as HTMLSelectElement).value);
    }
  });

  document.getElementById('history-retention')?.addEventListener('change', (e) => {
    if (pendingVaultSettings) {
      pendingVaultSettings.field_history_retention = valueToHistoryRetention((e.target as HTMLSelectElement).value);
    }
  });

  document.getElementById('save-retention')?.addEventListener('click', async () => {
    if (!pendingVaultSettings) return;
    const r = await sendMessage({ type: 'update_vault_settings', settings: pendingVaultSettings });
    if (!r.ok) alert(`Save failed: ${r.error}`);
  });
}

function trashRetentionToValue(r: TrashRetention): string {
  if (r.kind === 'forever') return 'forever';
  return `days:${r.value}`;
}

function valueToTrashRetention(v: string): TrashRetention {
  if (v === 'forever') return { kind: 'forever' };
  const m = /^days:(\d+)$/.exec(v);
  if (m) return { kind: 'days', value: Number(m[1]) };
  return { kind: 'forever' };
}

function historyRetentionToValue(r: HistoryRetention): string {
  if (r.kind === 'forever') return 'forever';
  if (r.kind === 'last_n') return `last_n:${r.value}`;
  return `days:${r.value}`;
}

function valueToHistoryRetention(v: string): HistoryRetention {
  if (v === 'forever') return { kind: 'forever' };
  const mLast = /^last_n:(\d+)$/.exec(v);
  if (mLast) return { kind: 'last_n', value: Number(mLast[1]) };
  const mDays = /^days:(\d+)$/.exec(v);
  if (mDays) return { kind: 'days', value: Number(mDays[1]) };
  return { kind: 'forever' };
}

function renderBackupSection(content: HTMLElement): void {
  content.innerHTML = `
    <h3 class="settings-section-title">Backup &amp; restore</h3>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Export &amp; restore backup</div>
        <div class="setting-row__desc">Download an encrypted backup or restore from a file. Opens in the vault tab.</div>
      </div>
      <div class="setting-row__control">
        <button class="btn" id="open-backup-tab" style="font-size:11px;">Open backup ▸</button>
      </div>
    </div>
  `;
  document.getElementById('open-backup-tab')?.addEventListener('click', () => openVaultTab('backup'));
}

function renderImportSection(content: HTMLElement): void {
  content.innerHTML = `
    <h3 class="settings-section-title">Import</h3>
    <div class="setting-row">
      <div class="setting-row__info">
        <div class="setting-row__title">Import from LastPass</div>
        <div class="setting-row__desc">Import a LastPass CSV export. Opens in the vault tab for review before committing.</div>
      </div>
      <div class="setting-row__control">
        <button class="btn" id="open-import-tab" style="font-size:11px;">Open import ▸</button>
      </div>
    </div>
  `;
  document.getElementById('open-import-tab')?.addEventListener('click', () => openVaultTab('import'));
}

export { renderAutofillSection, renderDisplaySection, renderGeneratorSection,
         renderRetentionSection, renderBackupSection, renderImportSection };

// Suppress unused-import warnings — these are used by Tasks 3-9
void sendMessage;
void loadColorScheme;
void saveColorScheme;
void resetColorScheme;
void DEFAULT_DIGIT_COLOR;
void DEFAULT_SYMBOL_COLOR;
void colorizePassword;
void openGeneratorPanel;
void pendingVaultSettings;
void activeKeyHandler;
