// State shared between popup and vault surfaces. Kept here (not in popup/) so
// shared/state.ts can import without creating a popup→shared circular dep.

import type {
  Item,
  ItemId,
  ItemType,
  ManifestEntry,
  GeneratorRequest,
  VaultSettings,
} from './types';

export type View =
  | 'locked'
  | 'list'
  | 'detail'
  | 'add'
  | 'edit'
  | 'settings'
  | 'settings-vault'
  | 'trash'
  | 'devices'
  | 'field-history'
  // Vault-tab-only views; popup never navigates to these. Kept in the union so
  // a single typed StateHost contract serves both surfaces (popup + vault).
  | 'history'
  | 'backup'
  | 'import';

export interface PopupState {
  view: View;
  entries: Array<[ItemId, ManifestEntry]>;
  selectedId: ItemId | null;
  selectedItem: Item | null;
  selectedIndex: number;
  searchQuery: string;
  activeGroup: string | null;
  error: string | null;
  loading: boolean;
  // Captured tab snapshot taken at popup-open. Used by fill_credentials
  // to guard against TOCTOU navigation — the SW re-checks this URL's
  // hostname against the tab's live URL before forwarding fill_credentials
  // to the content script. See router/popup-only.ts#handleFillCredentials.
  capturedTabId: number | null;
  capturedUrl: string;
  newType: ItemType | null;
  vaultSettings: VaultSettings | null;
  generatorDefaults: GeneratorRequest | null;
  historyItemId: ItemId | null;
  // Vault-tab-only fields. The popup surface leaves these at their defaults
  // (unlocked=false implicit via separate lock-screen view, drawer/panel false).
  // Kept on the shared shape so VaultState satisfies StateHost.getState()
  // without a cast.
  unlocked?: boolean;
  drawerOpen?: boolean;
  typePanelOpen?: boolean;
}
