/**
 * Adversarial Spotlight & Interaction Contract Verification Suite
 * Challenger M1_2 Empirical Harness
 */

import fs from "fs";
import path from "path";
import { ProcessedReceipt } from "../src/lib/schema/receipt";

// Simple assertion helper
function assert(condition: boolean, message: string) {
  if (!condition) {
    throw new Error(`[ASSERTION FAILED]: ${message}`);
  }
}

function assertEquals<T>(actual: T, expected: T, message: string) {
  if (actual !== expected) {
    throw new Error(`[ASSERTION FAILED]: ${message} | Expected: ${expected}, Got: ${actual}`);
  }
}

// Mock test receipt records
const mockReceipts: ProcessedReceipt[] = [
  {
    id: "rec-001",
    merchant: { name: "Aral Tankstelle", address: "München", taxId: "DE12345", confidence: 0.99 },
    date: { isoDate: "2026-08-15", time: "08:42", confidence: 0.98 },
    documentType: "KASSENBON",
    receiptNumber: "ARAL-9988",
    currency: "EUR",
    totalAmount: { value: 68.45, confidence: 0.99 },
    netAmount: 57.52,
    taxBreakdown: [{ ratePercent: 19, taxAmount: 10.93, netAmount: 57.52 }],
    lineItems: [{ description: "Super Plus", quantity: 35.1, unitPrice: 1.95, price: 68.45, taxRate: 19 }],
    suggestedCategory: "Tanken & KFZ",
    validation: {
      isMathValid: true,
      isDuplicateSuspected: false,
      needsUserReview: false,
      reviewField: "none",
      reviewReason: null,
    },
    imageHash: "hash-aral-001",
    originalFileName: "aral.jpg",
    fileSizeBytes: 184000,
    createdAt: "2026-08-15T08:42:00.000Z",
    updatedAt: "2026-08-15T08:42:00.000Z",
    status: "ready",
  },
  {
    id: "rec-002",
    merchant: { name: "Trattoria Bella Vista", address: "Berlin", taxId: "DE98765", confidence: 0.95 },
    date: { isoDate: "2026-08-14", time: "20:15", confidence: 0.95 },
    documentType: "BEWIRTUNGSBELEG",
    receiptNumber: "TRAT-1002",
    currency: "EUR",
    totalAmount: { value: 84.50, confidence: 0.96 },
    netAmount: 70.97,
    taxBreakdown: [
      { ratePercent: 7, taxAmount: 3.08, netAmount: 44.0 },
      { ratePercent: 19, taxAmount: 10.45, netAmount: 26.97 },
    ],
    lineItems: [
      { description: "Pasta Tartufo", quantity: 2, unitPrice: 22.0, price: 44.0, taxRate: 7 },
      { description: "Vino Rosso", quantity: 1, unitPrice: 28.0, price: 28.0, taxRate: 19 },
      { description: "Trinkgeld Bewirtung", quantity: 1, unitPrice: 12.5, price: 12.5, taxRate: 0 },
    ],
    suggestedCategory: "Bewirtung",
    validation: {
      isMathValid: true,
      isDuplicateSuspected: false,
      needsUserReview: false,
      reviewField: "none",
      reviewReason: null,
    },
    imageHash: "hash-trattoria-002",
    originalFileName: "trattoria.jpg",
    fileSizeBytes: 210000,
    createdAt: "2026-08-14T20:15:00.000Z",
    updatedAt: "2026-08-14T20:15:00.000Z",
    status: "ready",
  },
  {
    id: "rec-003",
    merchant: { name: "REWE City", address: "Köln", taxId: "DE554433", confidence: 0.94 },
    date: { isoDate: "2026-08-13", time: "17:30", confidence: 0.95 },
    documentType: "KASSENBON",
    receiptNumber: "REWE-7766",
    currency: "EUR",
    totalAmount: { value: 24.80, confidence: 0.95 },
    netAmount: 22.73,
    taxBreakdown: [
      { ratePercent: 7, taxAmount: 1.31, netAmount: 18.71 },
      { ratePercent: 19, taxAmount: 0.76, netAmount: 4.02 },
    ],
    lineItems: [
      { description: "Bio Milch", quantity: 2, unitPrice: 1.49, price: 2.98, taxRate: 7 },
      { description: "Dinkelbrot", quantity: 1, unitPrice: 3.49, price: 3.49, taxRate: 7 },
      { description: "Küchenrolle", quantity: 1, unitPrice: 4.78, price: 4.78, taxRate: 19 },
    ],
    suggestedCategory: "Material & Einkauf",
    validation: {
      isMathValid: false,
      isDuplicateSuspected: false,
      needsUserReview: true,
      reviewField: "taxBreakdown",
      reviewReason: "Abweichung",
    },
    imageHash: "hash-rewe-003",
    originalFileName: "rewe.jpg",
    fileSizeBytes: 165000,
    createdAt: "2026-08-13T17:30:00.000Z",
    updatedAt: "2026-08-13T17:30:00.000Z",
    status: "needs_review",
  },
];

// Replicate Spotlight Items generation logic for rigorous unit & contract testing
function buildCommandItems(options: {
  isDe: boolean;
  localReceipts: ProcessedReceipt[];
  onClose: () => void;
  onTriggerScan?: () => void;
  onLoadDemo?: () => void;
  onSelectReceipt?: (receipt: ProcessedReceipt) => void;
  routerPush: (path: string) => void;
}) {
  const { isDe, localReceipts, onClose, onTriggerScan, onLoadDemo, onSelectReceipt, routerPush } = options;

  const actionItems = [
    {
      id: "action-upload",
      title: isDe ? "+ Neuen Beleg hochladen / scannen" : "+ Upload / scan new receipt",
      subtitle: isDe ? "Öffnet Datei-Dialog für Kassenbon-Upload" : "Opens file picker for receipt upload",
      category: "actions" as const,
      badge: "SCAN",
      action: () => {
        onClose();
        if (onTriggerScan) {
          onTriggerScan();
        } else {
          routerPush("/dashboard");
        }
      },
    },
    {
      id: "action-demo",
      title: isDe ? "Demo-Belege laden" : "Load demo receipts",
      subtitle: isDe ? "Generiert Aral, Rewe & Trattoria Musterbelege" : "Seeds Aral, Rewe & Trattoria sample receipts",
      category: "actions" as const,
      badge: "DEMO",
      action: () => {
        onClose();
        if (onLoadDemo) {
          onLoadDemo();
        } else {
          routerPush("/dashboard");
        }
      },
    },
    {
      id: "action-excel",
      title: isDe ? "Excel-Export (.xlsx) erstellen" : "Generate Excel export (.xlsx)",
      subtitle: isDe ? "Dual-Sheet Arbeitsmappe mit dynamischen =SUM() Formeln" : "Dual-sheet workbook with dynamic =SUM() formulas",
      category: "actions" as const,
      badge: "XLSX",
      action: () => {
        onClose();
        routerPush("/dashboard/export");
      },
    },
    {
      id: "action-csv",
      title: isDe ? "Buchhaltungs-CSV exportieren" : "Export accounting CSV",
      subtitle: isDe ? "Semikolon, Dezimalkomma, UTF-8 BOM – öffnet in Excel" : "Semicolon, decimal commas, UTF-8 BOM – opens in Excel",
      category: "actions" as const,
      badge: "CSV",
      action: () => {
        onClose();
        routerPush("/dashboard/export");
      },
    },
  ];

  const receiptItems = localReceipts.map((r) => ({
    id: `receipt-${r.id}`,
    title: `${r.merchant?.name || "Unbekannter Händler"} • ${r.totalAmount?.value ? r.totalAmount.value.toFixed(2) + " €" : ""}`,
    subtitle: `${r.date?.isoDate || "Kein Datum"} • ${r.suggestedCategory || "Beleg"} ${r.receiptNumber ? "• #" + r.receiptNumber : ""}`,
    category: "receipts" as const,
    badge: r.validation?.isMathValid ? "VALID" : "REVIEW",
    action: () => {
      onClose();
      if (onSelectReceipt) {
        onSelectReceipt(r);
      } else {
        routerPush("/dashboard/activity");
      }
    },
  }));

  const navItems = [
    {
      id: "nav-overview",
      title: isDe ? "Dashboard Übersicht" : "Dashboard Overview",
      subtitle: "/dashboard",
      category: "navigation" as const,
      badge: "GOTO",
      action: () => {
        onClose();
        routerPush("/dashboard");
      },
    },
    {
      id: "nav-activity",
      title: isDe ? "Scan-Archiv & Belege" : "Scan Activity & Archive",
      subtitle: "/dashboard/activity",
      category: "navigation" as const,
      badge: "GOTO",
      action: () => {
        onClose();
        routerPush("/dashboard/activity");
      },
    },
    {
      id: "nav-export",
      title: isDe ? "Export-Zentrale (Excel & CSV)" : "Export Dispatcher (Excel & CSV)",
      subtitle: "/dashboard/export",
      category: "navigation" as const,
      badge: "GOTO",
      action: () => {
        onClose();
        routerPush("/dashboard/export");
      },
    },
    {
      id: "nav-settings",
      title: isDe ? "System- & KI-Einstellungen" : "System & AI Settings",
      subtitle: "/dashboard/settings",
      category: "navigation" as const,
      badge: "GOTO",
      action: () => {
        onClose();
        routerPush("/dashboard/settings");
      },
    },
    {
      id: "nav-landing",
      title: isDe ? "Landing Page & Hero Scanner" : "Landing Page & Hero Scanner",
      subtitle: "/",
      category: "navigation" as const,
      badge: "HOME",
      action: () => {
        onClose();
        routerPush("/");
      },
    },
  ];

  return { actionItems, receiptItems, navItems };
}

function filterCommandItems(
  items: { actionItems: any[]; receiptItems: any[]; navItems: any[] },
  query: string
) {
  const q = query.toLowerCase().trim();
  const filteredActions = items.actionItems.filter(
    (item) => item.title.toLowerCase().includes(q) || item.subtitle?.toLowerCase().includes(q)
  );
  const filteredReceipts = items.receiptItems.filter(
    (item) => item.title.toLowerCase().includes(q) || item.subtitle?.toLowerCase().includes(q)
  );
  const filteredNav = items.navItems.filter(
    (item) => item.title.toLowerCase().includes(q) || item.subtitle?.toLowerCase().includes(q)
  );

  return {
    filteredActions,
    filteredReceipts,
    filteredNav,
    filteredItems: [...filteredActions, ...filteredReceipts, ...filteredNav],
  };
}

// ----------------- TEST SUITE -----------------

console.log("================================================================");
console.log("ADVERSARIAL CHALLENGER M1_2: SPOTLIGHT & INTERACTION CONTRACTS");
console.log("================================================================\n");

let passed = 0;
let total = 0;

function runTest(name: string, fn: () => void) {
  total++;
  try {
    fn();
    console.log(`  ✓ ${name}`);
    passed++;
  } catch (err: any) {
    console.error(`  ✗ ${name}`);
    console.error(`    ${err.message}`);
    throw err;
  }
}

// 1. Keyboard Shortcut Listener Tests (TopNav.tsx & Global contracts)
runTest("TopNav keydown: Cmd+k triggers modal toggle on macOS", () => {
  let isOpen = false;
  const toggle = () => { isOpen = !isOpen; };

  const eventMac = { metaKey: true, ctrlKey: false, key: "k", defaultPrevented: false, preventDefault() { this.defaultPrevented = true; } };
  if ((eventMac.metaKey || eventMac.ctrlKey) && eventMac.key.toLowerCase() === "k") {
    eventMac.preventDefault();
    toggle();
  }

  assertEquals(isOpen, true, "Spotlight should open on metaKey + k");
  assertEquals(eventMac.defaultPrevented, true, "Default event should be prevented");
});

runTest("TopNav keydown: Ctrl+k triggers modal toggle on Windows/Linux", () => {
  let isOpen = false;
  const toggle = () => { isOpen = !isOpen; };

  const eventWin = { metaKey: false, ctrlKey: true, key: "k", defaultPrevented: false, preventDefault() { this.defaultPrevented = true; } };
  if ((eventWin.metaKey || eventWin.ctrlKey) && eventWin.key.toLowerCase() === "k") {
    eventWin.preventDefault();
    toggle();
  }

  assertEquals(isOpen, true, "Spotlight should open on ctrlKey + k");
  assertEquals(eventWin.defaultPrevented, true, "Default event should be prevented");
});

runTest("TopNav keydown: Case-insensitive 'K' (Caps Lock or Shift) is recognized", () => {
  let isOpen = false;
  const toggle = () => { isOpen = !isOpen; };

  const eventShift = { metaKey: true, ctrlKey: false, key: "K", defaultPrevented: false, preventDefault() { this.defaultPrevented = true; } };
  if ((eventShift.metaKey || eventShift.ctrlKey) && eventShift.key.toLowerCase() === "k") {
    eventShift.preventDefault();
    toggle();
  }

  assertEquals(isOpen, true, "Spotlight should open on metaKey + uppercase K");
});

runTest("TopNav keydown: Unrelated keys (e.g. Cmd+S, Ctrl+P, 'k' alone) do NOT trigger Spotlight", () => {
  let isOpen = false;
  const toggle = () => { isOpen = !isOpen; };

  const tests = [
    { metaKey: true, ctrlKey: false, key: "s" },
    { metaKey: false, ctrlKey: true, key: "p" },
    { metaKey: false, ctrlKey: false, key: "k" },
    { metaKey: true, ctrlKey: false, key: "Meta" },
  ];

  for (const e of tests) {
    if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
      toggle();
    }
  }

  assertEquals(isOpen, false, "Spotlight should not open on non-K shortcuts or K without modifier");
});

// 2. SpotlightDialog Arrow Navigation & Selection
runTest("SpotlightDialog keydown: ArrowDown navigates cyclically", () => {
  const items = [1, 2, 3, 4];
  let selectedIndex = 0;

  const navigateDown = () => {
    selectedIndex = items.length > 0 ? (selectedIndex + 1) % items.length : 0;
  };

  navigateDown(); // 1
  assertEquals(selectedIndex, 1, "Should move to index 1");
  navigateDown(); // 2
  assertEquals(selectedIndex, 2, "Should move to index 2");
  navigateDown(); // 3
  assertEquals(selectedIndex, 3, "Should move to index 3");
  navigateDown(); // 0 (wrap-around)
  assertEquals(selectedIndex, 0, "Should wrap around to index 0");
});

runTest("SpotlightDialog keydown: ArrowUp navigates cyclically backwards", () => {
  const items = [1, 2, 3, 4];
  let selectedIndex = 0;

  const navigateUp = () => {
    selectedIndex = items.length > 0 ? (selectedIndex - 1 + items.length) % items.length : 0;
  };

  navigateUp(); // 3 (wrap-around backwards)
  assertEquals(selectedIndex, 3, "Should wrap backwards to index 3");
  navigateUp(); // 2
  assertEquals(selectedIndex, 2, "Should move to index 2");
  navigateUp(); // 1
  assertEquals(selectedIndex, 1, "Should move to index 1");
  navigateUp(); // 0
  assertEquals(selectedIndex, 0, "Should move to index 0");
});

runTest("SpotlightDialog keydown: Arrow navigation with empty results does not throw or return NaN", () => {
  const items: any[] = [];
  let selectedIndex = 0;

  const navigateDown = () => {
    selectedIndex = items.length > 0 ? (selectedIndex + 1) % items.length : 0;
  };
  const navigateUp = () => {
    selectedIndex = items.length > 0 ? (selectedIndex - 1 + items.length) % items.length : 0;
  };

  navigateDown();
  assertEquals(selectedIndex, 0, "Empty list down should be 0");
  navigateUp();
  assertEquals(selectedIndex, 0, "Empty list up should be 0");
  assert(!Number.isNaN(selectedIndex), "Index must not be NaN");
});

runTest("SpotlightDialog keydown: Escape triggers onClose", () => {
  let closed = false;
  const onClose = () => { closed = true; };

  const eventEsc = { key: "Escape", defaultPrevented: false, preventDefault() { this.defaultPrevented = true; } };
  if (eventEsc.key === "Escape") {
    eventEsc.preventDefault();
    onClose();
  }

  assertEquals(closed, true, "Escape must close dialog");
  assertEquals(eventEsc.defaultPrevented, true, "Escape must prevent default");
});

runTest("SpotlightDialog keydown: Enter invokes action of selected item", () => {
  let actionExecuted = false;
  const items = [
    { id: "1", action: () => { actionExecuted = false; } },
    { id: "2", action: () => { actionExecuted = true; } },
  ];
  const selectedIndex = 1;

  const eventEnter = { key: "Enter", defaultPrevented: false, preventDefault() { this.defaultPrevented = true; } };
  if (eventEnter.key === "Enter") {
    eventEnter.preventDefault();
    if (items[selectedIndex]) {
      items[selectedIndex].action();
    }
  }

  assertEquals(actionExecuted, true, "Enter must execute selected item action");
  assertEquals(eventEnter.defaultPrevented, true, "Enter must prevent default");
});

runTest("SpotlightDialog keydown: Enter with empty list is safely ignored", () => {
  const items: any[] = [];
  const selectedIndex = 0;
  let executed = false;

  if (items[selectedIndex]) {
    items[selectedIndex].action();
    executed = true;
  }

  assertEquals(executed, false, "Enter on empty list should do nothing safely");
});

// 3. Search Filtering Adversarial Cases
runTest("Search Filtering: Empty query returns all 4 actions, all receipts, and all 5 navigation links", () => {
  let closed = false;
  let pushedRoute = "";
  const items = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => { closed = true; },
    routerPush: (p) => { pushedRoute = p; },
  });

  const { filteredActions, filteredReceipts, filteredNav, filteredItems } = filterCommandItems(items, "");
  assertEquals(filteredActions.length, 4, "Should have 4 actions");
  assertEquals(filteredReceipts.length, 3, "Should have 3 receipts");
  assertEquals(filteredNav.length, 5, "Should have 5 navigation links");
  assertEquals(filteredItems.length, 12, "Total items should be 12");
});

runTest("Search Filtering: Case-insensitive & whitespace trimmed matching", () => {
  const items = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => {},
    routerPush: () => {},
  });

  const r1 = filterCommandItems(items, "   ARAL   ");
  assertEquals(r1.filteredReceipts.length, 1, "Should find Aral receipt");
  assertEquals(r1.filteredReceipts[0].title.includes("Aral"), true, "Title must contain Aral");

  const r2 = filterCommandItems(items, "TrAtToRiA");
  assertEquals(r2.filteredReceipts.length, 1, "Should find Trattoria receipt");

  const r3 = filterCommandItems(items, "   rewe   ");
  assertEquals(r3.filteredReceipts.length, 1, "Should find Rewe receipt");
});

runTest("Search Filtering: Filter by currency amount and receipt number", () => {
  const items = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => {},
    routerPush: () => {},
  });

  // Search by amount "68.45"
  const rAmount = filterCommandItems(items, "68.45");
  assertEquals(rAmount.filteredReceipts.length, 1, "Should match 68.45 €");
  assertEquals(rAmount.filteredReceipts[0].id, "receipt-rec-001", "Should be Aral receipt");

  // Search by receipt number "TRAT-1002"
  const rNum = filterCommandItems(items, "TRAT-1002");
  assertEquals(rNum.filteredReceipts.length, 1, "Should match receipt number TRAT-1002");
  assertEquals(rNum.filteredReceipts[0].id, "receipt-rec-002", "Should be Trattoria receipt");
});

runTest("Search Filtering: Filter by category tag (e.g. Bewirtung, Tanken)", () => {
  const items = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => {},
    routerPush: () => {},
  });

  const rCat = filterCommandItems(items, "Bewirtung");
  assertEquals(rCat.filteredReceipts.length, 1, "Should match Bewirtung category");
  assertEquals(rCat.filteredReceipts[0].id, "receipt-rec-002", "Should be Trattoria");
});

runTest("Search Filtering: Filter by Action names (e.g. 'Excel', 'CSV', 'Demo', 'Upload')", () => {
  const items = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => {},
    routerPush: () => {},
  });

  // Both export actions legitimately mention Excel (the CSV opens in it), so a
  // bare "Excel" query must return both — filtering by the format token is what
  // has to disambiguate them.
  const rExcel = filterCommandItems(items, "Excel");
  assertEquals(rExcel.filteredActions.length, 2, "Should find both export actions");

  const rXlsx = filterCommandItems(items, ".xlsx");
  assertEquals(rXlsx.filteredActions.length, 1, "Should find Excel action");
  assertEquals(rXlsx.filteredActions[0].id, "action-excel", "ID must be action-excel");

  const rCsv = filterCommandItems(items, "CSV");
  assertEquals(rCsv.filteredActions.length, 1, "Should find accounting CSV action");
  assertEquals(rCsv.filteredActions[0].id, "action-csv", "ID must be action-csv");
});

runTest("Search Filtering: Filter by navigation path (e.g. '/dashboard/export', 'settings')", () => {
  const items = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => {},
    routerPush: () => {},
  });

  const rSettings = filterCommandItems(items, "settings");
  assertEquals(rSettings.filteredNav.length, 1, "Should find settings nav item");
  assertEquals(rSettings.filteredNav[0].id, "nav-settings", "ID must be nav-settings");

  const rActivity = filterCommandItems(items, "/dashboard/activity");
  assertEquals(rActivity.filteredNav.length, 1, "Should find activity nav item by route substring");
});

runTest("Search Filtering: Zero-match search returns empty results gracefully", () => {
  const items = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => {},
    routerPush: () => {},
  });

  const rNone = filterCommandItems(items, "XYZ999NONEXISTENT");
  assertEquals(rNone.filteredItems.length, 0, "No items should match");
  assertEquals(rNone.filteredActions.length, 0, "No actions");
  assertEquals(rNone.filteredReceipts.length, 0, "No receipts");
  assertEquals(rNone.filteredNav.length, 0, "No nav");
});

// 4. Action Invocation & Routing Verification
runTest("Action Invocation: Quick Action 'upload' calls onClose and custom trigger or router fallback", () => {
  let closed = false;
  let scanTriggered = false;
  let pushedRoute = "";

  const itemsWithTrigger = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => { closed = true; },
    onTriggerScan: () => { scanTriggered = true; },
    routerPush: (p) => { pushedRoute = p; },
  });

  itemsWithTrigger.actionItems.find((a) => a.id === "action-upload")?.action();
  assertEquals(closed, true, "onClose must be called");
  assertEquals(scanTriggered, true, "onTriggerScan must be called");
  assertEquals(pushedRoute, "", "routerPush should not be called when onTriggerScan is provided");

  // Test fallback without onTriggerScan
  closed = false;
  pushedRoute = "";
  const itemsWithoutTrigger = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => { closed = true; },
    routerPush: (p) => { pushedRoute = p; },
  });
  itemsWithoutTrigger.actionItems.find((a) => a.id === "action-upload")?.action();
  assertEquals(closed, true, "onClose must be called");
  assertEquals(pushedRoute, "/dashboard", "routerPush should fallback to /dashboard");
});

runTest("Action Invocation: Quick Action 'demo' calls onClose and custom trigger or router fallback", () => {
  let closed = false;
  let demoTriggered = false;
  let pushedRoute = "";

  const itemsWithDemo = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => { closed = true; },
    onLoadDemo: () => { demoTriggered = true; },
    routerPush: (p) => { pushedRoute = p; },
  });

  itemsWithDemo.actionItems.find((a) => a.id === "action-demo")?.action();
  assertEquals(closed, true, "onClose must be called");
  assertEquals(demoTriggered, true, "onLoadDemo must be called");

  // Fallback
  closed = false;
  const itemsWithoutDemo = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => { closed = true; },
    routerPush: (p) => { pushedRoute = p; },
  });
  itemsWithoutDemo.actionItems.find((a) => a.id === "action-demo")?.action();
  assertEquals(closed, true, "onClose must be called");
  assertEquals(pushedRoute, "/dashboard", "routerPush should fallback to /dashboard");
});

runTest("Action Invocation: Quick Actions 'excel' and 'csv' route to /dashboard/export", () => {
  let closed = false;
  let pushedRoute = "";

  const items = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => { closed = true; },
    routerPush: (p) => { pushedRoute = p; },
  });

  items.actionItems.find((a) => a.id === "action-excel")?.action();
  assertEquals(closed, true, "onClose must be called");
  assertEquals(pushedRoute, "/dashboard/export", "Must route to /dashboard/export");

  closed = false;
  pushedRoute = "";
  items.actionItems.find((a) => a.id === "action-csv")?.action();
  assertEquals(closed, true, "onClose must be called");
  assertEquals(pushedRoute, "/dashboard/export", "Must route to /dashboard/export");
});

runTest("Action Invocation: Receipt item selection calls onSelectReceipt or routes to /dashboard/activity", () => {
  let closed = false;
  let selectedReceipt: any = null;
  let pushedRoute = "";

  const itemsWithSelect = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => { closed = true; },
    onSelectReceipt: (r) => { selectedReceipt = r; },
    routerPush: (p) => { pushedRoute = p; },
  });

  itemsWithSelect.receiptItems[0].action();
  assertEquals(closed, true, "onClose must be called");
  assertEquals(selectedReceipt?.id, "rec-001", "Selected receipt must match rec-001");

  // Fallback
  closed = false;
  const itemsWithoutSelect = buildCommandItems({
    isDe: true,
    localReceipts: mockReceipts,
    onClose: () => { closed = true; },
    routerPush: (p) => { pushedRoute = p; },
  });
  itemsWithoutSelect.receiptItems[0].action();
  assertEquals(closed, true, "onClose must be called");
  assertEquals(pushedRoute, "/dashboard/activity", "Must route to /dashboard/activity on fallback");
});

runTest("Action Invocation: Navigation links route to their respective pages", () => {
  const routes = [
    { id: "nav-overview", expected: "/dashboard" },
    { id: "nav-activity", expected: "/dashboard/activity" },
    { id: "nav-export", expected: "/dashboard/export" },
    { id: "nav-settings", expected: "/dashboard/settings" },
    { id: "nav-landing", expected: "/" },
  ];

  for (const r of routes) {
    let closed = false;
    let pushedRoute = "";
    const items = buildCommandItems({
      isDe: true,
      localReceipts: mockReceipts,
      onClose: () => { closed = true; },
      routerPush: (p) => { pushedRoute = p; },
    });

    const item = items.navItems.find((n) => n.id === r.id);
    assert(item !== undefined, `Nav item ${r.id} should exist`);
    item?.action();
    assertEquals(closed, true, `onClose must be called for ${r.id}`);
    assertEquals(pushedRoute, r.expected, `Target path must be ${r.expected}`);
  }
});

// 5. English Localization Verification
runTest("Localization: English strings render appropriately when language === 'en'", () => {
  const itemsEn = buildCommandItems({
    isDe: false,
    localReceipts: mockReceipts,
    onClose: () => {},
    routerPush: () => {},
  });

  assertEquals(itemsEn.actionItems[0].title.startsWith("+ Upload / scan"), true, "English action title");
  assertEquals(itemsEn.actionItems[1].title, "Load demo receipts", "English demo title");
  assertEquals(itemsEn.navItems[0].title, "Dashboard Overview", "English overview nav title");
});

// 6. Source Code Static Token & Lifecycle Invariant Audits
runTest("Source Audit: SpotlightDialog.tsx contains zero rounded-, shadow-, or gradient classes", () => {
  const spotlightCode = fs.readFileSync(path.resolve(__dirname, "../src/components/dashboard/SpotlightDialog.tsx"), "utf-8");
  const forbiddenPatterns = [
    /\brounded(-[a-z0-9]+)?\b/g,
    /\bshadow(-[a-z0-9]+)?\b/g,
    /\bbg-gradient-[a-z0-9-]+\b/g,
  ];

  for (const pattern of forbiddenPatterns) {
    const matches = spotlightCode.match(pattern);
    assertEquals(matches, null, `Found forbidden style match ${matches} in SpotlightDialog.tsx`);
  }
});

runTest("Source Audit: TopNav.tsx contains zero rounded-, shadow-, or gradient classes", () => {
  const topNavCode = fs.readFileSync(path.resolve(__dirname, "../src/components/dashboard/TopNav.tsx"), "utf-8");
  const forbiddenPatterns = [
    /\brounded(-[a-z0-9]+)?\b/g,
    /\bshadow(-[a-z0-9]+)?\b/g,
    /\bbg-gradient-[a-z0-9-]+\b/g,
  ];

  for (const pattern of forbiddenPatterns) {
    const matches = topNavCode.match(pattern);
    assertEquals(matches, null, `Found forbidden style match ${matches} in TopNav.tsx`);
  }
});

runTest("Source Audit: Both TopNav.tsx and SpotlightDialog.tsx properly unbind keydown event listeners", () => {
  const topNavCode = fs.readFileSync(path.resolve(__dirname, "../src/components/dashboard/TopNav.tsx"), "utf-8");
  const spotlightCode = fs.readFileSync(path.resolve(__dirname, "../src/components/dashboard/SpotlightDialog.tsx"), "utf-8");

  assert(topNavCode.includes('window.removeEventListener("keydown"'), "TopNav must unbind keydown");
  assert(spotlightCode.includes('window.removeEventListener("keydown"'), "SpotlightDialog must unbind keydown");
});

console.log("\n================================================================");
console.log(`RESULTS: ${passed} / ${total} TESTS PASSED (100% SUCCESS)`);
console.log("================================================================\n");
