// Vault-tab shell: render entry point, lock screen, 3-column shell
// scaffolding, the right-side type-picker panel, color-scheme apply, and the
// session_expired listener. Each function receives the VaultController (`ctx`)
// and reaches sibling concerns through it; pure helpers come from
// vault-context. vault.ts owns the state singleton and assembles the ctx.

import type { ItemType } from '../shared/types';
import { lookupErrorCopy } from '../shared/error-copy';
import { applyColorScheme } from '../shared/color-scheme';
import {
  type VaultController, escapeHtml, typeIcon,
} from './vault-context';
import { renderSidebarShell } from './vault-sidebar';

// ---------------------------------------------------------------------------
// Type picker (right side panel)
// ---------------------------------------------------------------------------

const PICKER_TYPES: Array<{ type: ItemType; label: string }> = [
  { type: 'login',       label: 'Login' },
  { type: 'secure_note', label: 'Secure Note' },
  { type: 'totp',        label: 'TOTP' },
  { type: 'card',        label: 'Card' },
  { type: 'identity',    label: 'Identity' },
  { type: 'key',         label: 'SSH / API Key' },
  { type: 'document',    label: 'Document' },
];

// ---------------------------------------------------------------------------
// Render entry point
// ---------------------------------------------------------------------------

export function render(ctx: VaultController): void {
  const app = document.getElementById('vault-app');
  if (!app) return;

  if (!ctx.state.unlocked) {
    renderLockScreen(ctx, app);
  } else {
    renderShell(ctx, app);
  }
}

// ---------------------------------------------------------------------------
// Lock screen
// ---------------------------------------------------------------------------

function renderErrorBlock(code: string | null | undefined): string {
  if (!code) return '';
  const copy = lookupErrorCopy(code);
  const ctaHtml = copy.cta
    ? `<button class="btn btn-primary error-cta" data-cta="${escapeHtml(copy.cta.action ?? '')}">${escapeHtml(copy.cta.label)}</button>`
    : '';
  return `
    <div class="error error-block">
      <div class="error-title">${escapeHtml(copy.title)}</div>
      <div class="error-body">${escapeHtml(copy.body)}</div>
      ${ctaHtml}
    </div>
  `;
}

export function renderLockScreen(ctx: VaultController, app: HTMLElement): void {
  app.innerHTML = `
    <div class="vault-lock-screen">
      <img class="brand-logo" src="icons/relicario-logo.svg" alt="">
      <span class="brand">Relicario</span>
      <div class="vault-lock-screen__form">
        <input type="password" id="vault-passphrase" placeholder="passphrase" autocomplete="off" />
        <button class="btn btn-primary" id="vault-unlock-btn" style="width:100%;">unlock</button>
        ${renderErrorBlock(ctx.state.error)}
      </div>
    </div>
  `;

  const input = document.getElementById('vault-passphrase') as HTMLInputElement;
  const btn = document.getElementById('vault-unlock-btn')!;

  const doUnlock = async () => {
    const passphrase = input.value;
    if (!passphrase) return;
    btn.textContent = 'unlocking...';
    btn.setAttribute('disabled', 'true');
    const resp = await ctx.sendMessage({ type: 'unlock', passphrase });
    if (resp.ok) {
      ctx.state.unlocked = true;
      ctx.state.error = null;
      await ctx.loadManifest();
      render(ctx);
    } else {
      ctx.state.error = resp.error ?? 'unlock failed';
      render(ctx);
    }
  };

  btn.addEventListener('click', doUnlock);
  input.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') doUnlock();
  });
  input.focus();
}

// ---------------------------------------------------------------------------
// Shell (3-column: sidebar + list pane + drawer)
// ---------------------------------------------------------------------------

export function renderShell(ctx: VaultController, app: HTMLElement): void {
  if (!app.querySelector('.vault-shell')) {
    app.innerHTML = `
      <div class="vault-shell">
        ${renderSidebarShell()}
        <div class="vault-list-pane" id="vault-list-pane"></div>
        <div class="vault-pane" id="vault-pane"></div>
        <div class="vault-drawer" id="vault-drawer"></div>
        <div class="vault-type-panel-scrim" id="vault-type-scrim"></div>
        <aside class="vault-type-panel" id="vault-type-panel" aria-label="Choose item type"></aside>
      </div>
    `;
    ctx.wireSidebar();
    wireTypePanel(ctx);
  }

  applyShellViewClass(ctx);
  ctx.renderSidebarCategories();
  if (ctx.state.view === 'list') {
    ctx.renderListPane();
    if (ctx.state.drawerOpen && ctx.state.selectedItem) {
      ctx.renderDrawer(ctx.state.selectedItem);
    }
  } else {
    ctx.renderPane();
  }
}

// Toggle which middle column is visible based on the current view.
// list view → list-pane (+ optional drawer); other views → vault-pane.
export function applyShellViewClass(ctx: VaultController): void {
  const shell = document.querySelector('.vault-shell');
  if (!shell) return;
  shell.classList.toggle('vault-shell--list', ctx.state.view === 'list');
  shell.classList.toggle('vault-shell--pane', ctx.state.view !== 'list');
}

// ---------------------------------------------------------------------------
// Right-side type picker panel
// ---------------------------------------------------------------------------

export function wireTypePanel(ctx: VaultController): void {
  document.getElementById('vault-type-scrim')?.addEventListener('click', () => closeTypePanel(ctx));
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && ctx.state.typePanelOpen) closeTypePanel(ctx);
  });
}

export function openTypePanel(ctx: VaultController): void {
  const panel = document.getElementById('vault-type-panel');
  const scrim = document.getElementById('vault-type-scrim');
  if (!panel || !scrim) return;

  panel.innerHTML = `
    <div class="vault-type-panel__head">
      <div class="vault-type-panel__title">New item</div>
      <button class="vault-type-panel__close" id="vault-type-close" title="Close (Esc)" aria-label="Close">✕</button>
    </div>
    <div class="vault-type-panel__hint">Choose a type</div>
    <div class="vault-type-list" role="menu">
      ${PICKER_TYPES.map((t) => `
        <button class="vault-type-item" data-type="${t.type}" role="menuitem">
          <span class="vault-type-item__icon" aria-hidden="true">${typeIcon(t.type)}</span>
          <span class="vault-type-item__name">${escapeHtml(t.label)}</span>
        </button>
      `).join('')}
    </div>
  `;

  panel.classList.add('vault-type-panel--open');
  scrim.classList.add('vault-type-panel-scrim--visible');
  ctx.state.typePanelOpen = true;

  panel.querySelector('#vault-type-close')?.addEventListener('click', () => closeTypePanel(ctx));

  panel.querySelectorAll<HTMLButtonElement>('[data-type]').forEach((btn) => {
    btn.addEventListener('click', () => {
      const type = btn.dataset.type as ItemType;
      closeTypePanel(ctx);
      // Use the host's navigate hook so view + hash + visibility all update
      // together. This was the bug: bare setHash + renderPane left the
      // shell stuck in list view with #vault-pane hidden.
      ctx.state.newType = type;
      ctx.state.selectedId = null;
      ctx.state.selectedItem = null;
      ctx.state.drawerOpen = false;
      ctx.state.view = 'add';
      ctx.setHash('add', type);
      applyShellViewClass(ctx);
      ctx.renderSidebarCategories();
      ctx.renderPane();
    });
  });

  // Focus first item for keyboard users
  (panel.querySelector('.vault-type-item') as HTMLElement | null)?.focus();
}

export function closeTypePanel(ctx: VaultController): void {
  document.getElementById('vault-type-panel')?.classList.remove('vault-type-panel--open');
  document.getElementById('vault-type-scrim')?.classList.remove('vault-type-panel-scrim--visible');
  ctx.state.typePanelOpen = false;
}

// ---------------------------------------------------------------------------
// Color scheme + session-expired wiring (bootstrap helpers)
// ---------------------------------------------------------------------------

export async function applyVaultColorScheme(): Promise<void> {
  await applyColorScheme();

  chrome.storage.onChanged.addListener((changes, area) => {
    if (area === 'sync' && 'password_display_scheme' in changes) {
      void applyColorScheme();
    }
  });
}

export function wireSessionExpiredListener(ctx: VaultController): void {
  chrome.runtime.onMessage.addListener((msg) => {
    if (msg.type === 'session_expired') {
      ctx.state.unlocked = false;
      ctx.state.selectedId = null;
      ctx.state.selectedItem = null;
      ctx.state.entries = [];
      ctx.state.error = null;
      render(ctx);
    }
  });
}
