// Vault-tab routing core: hash parsing/serialization, pane dispatch (delegating
// to the shared popup components), and data loading. Receives the
// VaultController (`ctx`) and reaches sibling concerns through it. Imports only
// from shared/, the popup components, vault-context, vault-drawer, and
// vault-form-wrapper — never from vault.ts or the shell/sidebar/list modules.

import type {
  ItemId, ItemType, ManifestEntry, Item, VaultSettings,
} from '../shared/types';
import { renderItemDetail } from '../popup/components/item-detail';
import { renderItemForm } from '../popup/components/item-form';
import { renderTrash, teardown as teardownTrash } from '../popup/components/trash';
import { renderDevices, teardown as teardownDevices } from '../popup/components/devices';
import { renderSettings, teardownSettings } from '../popup/components/settings';
import { renderVaultSettings as renderVaultSettingsView } from '../popup/components/settings-vault';
import { renderFieldHistory, teardown as teardownFieldHistory } from '../popup/components/field-history';
import { renderItemHistoryIndex, teardown as teardownHistoryIndex } from '../popup/components/item-history-index';
import { renderBackupPanel, teardown as teardownBackup } from './components/backup-panel';
import { renderImportPanel, teardown as teardownImport } from './components/import-panel';
import {
  type VaultController, type VaultView, type HashRoute,
} from './vault-context';
import { ensureDrawerClosedForRoute } from './vault-drawer';
import { renderFormWrapped } from './vault-form-wrapper';

// ---------------------------------------------------------------------------
// Hash routing
// ---------------------------------------------------------------------------

export function parseHash(): HashRoute {
  let raw = window.location.hash.replace(/^#\/?/, '');
  if (!raw) return { view: 'list' };

  // Normalize legacy bookmarks: #field-history/<id> → #history/<id>
  if (raw.startsWith('field-history/')) {
    raw = 'history/' + raw.slice('field-history/'.length);
    window.location.hash = raw;
  }

  const parts = raw.split('/');
  const view = parts[0] as VaultView;

  switch (view) {
    case 'detail':
    case 'edit':
      return { view, id: parts[1] };
    case 'add':
      return { view, type: parts[1] };
    case 'history':
      return parts[1]
        ? { view: 'field-history', id: parts[1] }
        : { view: 'history' };
    case 'trash':
    case 'devices':
    case 'settings':
    case 'settings-vault':
    case 'field-history':
    case 'backup':
    case 'import':
      return { view };
    default:
      return { view: 'list' };
  }
}

export function setHash(view: VaultView, param?: string): void {
  const fragment = param ? `${view}/${param}` : view;
  window.location.hash = fragment === 'list' ? '' : fragment;
}

// ---------------------------------------------------------------------------
// Pane rendering — delegates to shared popup components
// ---------------------------------------------------------------------------

function teardownPaneComponents(): void {
  teardownTrash();
  teardownDevices();
  teardownSettings();
  teardownFieldHistory();
  teardownHistoryIndex();
  teardownBackup();
  teardownImport();
}

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

  teardownPaneComponents();

  const route = parseHash();
  ensureDrawerClosedForRoute(ctx.state, route);
  // Keep state.view in sync with hash for components that read it
  ctx.state.view = route.view;
  ctx.applyShellViewClass();

  pane.className = 'vault-pane';

  switch (route.view) {
    case 'detail':
      if (ctx.state.selectedItem) {
        renderItemDetail(pane);
      } else {
        pane.className = 'vault-pane vault-pane--empty';
        pane.innerHTML = 'select an item';
      }
      break;
    case 'add':
      // Prefer hash type for deep-links; otherwise keep the in-memory value
      // set by the type-selection click handler (which calls setState →
      // renderPane before the URL hash has been updated to include the type).
      ctx.state.newType = (route.type as ItemType) ?? ctx.state.newType ?? null;
      // Use the form wrapper (sticky bar + header) when a type is already chosen.
      // Without a type the type-selection screen renders — no sticky bar needed.
      if (ctx.state.newType) {
        renderFormWrapped(ctx, pane, 'add');
      } else {
        renderItemForm(pane, 'add');
      }
      break;
    case 'edit':
      renderFormWrapped(ctx, pane, 'edit');
      break;
    case 'trash':
      renderTrash(pane);
      break;
    case 'devices':
      renderDevices(pane);
      break;
    case 'settings':
      void renderSettings(pane);
      break;
    case 'settings-vault':
      renderVaultSettingsView(pane);
      break;
    case 'field-history':
      renderFieldHistory(pane);
      break;
    case 'history':
      renderItemHistoryIndex(pane);
      break;
    case 'backup':
      renderBackupPanel(pane);
      break;
    case 'import':
      renderImportPanel(pane);
      break;
    default:
      pane.className = 'vault-pane vault-pane--empty';
      pane.innerHTML = 'select an item';
      break;
  }
}

// ---------------------------------------------------------------------------
// Data loading
// ---------------------------------------------------------------------------

export async function loadManifest(ctx: VaultController): Promise<void> {
  const listResp = await ctx.sendMessage({ type: 'list_items' });
  if (listResp.ok) {
    const data = listResp.data as { items: Array<[ItemId, ManifestEntry]> };
    ctx.state.entries = data.items;
  }

  const vsResp = await ctx.sendMessage({ type: 'get_vault_settings' });
  if (vsResp.ok) {
    const data = vsResp.data as { settings: VaultSettings };
    ctx.state.vaultSettings = data.settings;
    ctx.state.generatorDefaults = data.settings.generator_defaults;
  }

  // Handle deep link from hash
  const route = parseHash();
  if (route.view === 'detail' && route.id) {
    const itemResp = await ctx.sendMessage({ type: 'get_item', id: route.id });
    if (itemResp.ok) {
      const data = itemResp.data as { item: Item };
      ctx.state.selectedId = route.id;
      ctx.state.selectedItem = data.item;
    }
  }
}

// ---------------------------------------------------------------------------
// Legacy selectItem — used by hash-change deep linking
// ---------------------------------------------------------------------------

export async function selectItem(ctx: VaultController, id: ItemId): Promise<void> {
  ctx.state.loading = true;
  const resp = await ctx.sendMessage({ type: 'get_item', id });
  if (resp.ok) {
    const data = resp.data as { item: Item };
    ctx.state.selectedId = id;
    ctx.state.selectedItem = data.item;
    ctx.state.loading = false;
    setHash('detail', id);
    ctx.renderSidebarCategories();
    ctx.renderListPane();
    renderPane(ctx);
  } else {
    ctx.state.loading = false;
    ctx.state.error = (resp as { error: string }).error;
  }
}
