// @ts-nocheck
import * as React from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';

const LAST_UPDATED = '2026-06-02';
const BACKEND_TABLES_IMPLEMENTED = 9;
const BACKEND_TABLES_DESIGNED = 56;
const BACKEND_REDUCERS_IMPLEMENTED = 12;
const BACKEND_REDUCERS_DESIGNED = 40;

type Phase = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7';
type Layer = 'backend' | 'frontend' | 'scene' | 'prototype';
type Status = 'done' | 'partial' | 'missing' | 'blocked';

interface TodoItem {
  id: string;
  title: string;
  phase: Phase;
  layer: Layer;
  status: Status;
  desc: string;
  detail?: string;
  files?: string;
  blockedBy?: string[];
}

const STATUS_COLORS: Record<Status, string> = {
  done: 'var(--green)',
  partial: 'var(--accent)',
  missing: 'var(--red)',
  blocked: 'var(--muted)',
};

const STATUS_LABELS: Record<Status, string> = {
  done: 'DONE',
  partial: 'PARTIAL',
  missing: 'MISSING',
  blocked: 'BLOCKED',
};

const LAYER_LABELS: Record<Layer, string> = {
  backend: 'SpacetimeDB',
  frontend: 'Game UI',
  scene: '3D Scene',
  prototype: 'Prototype Ready',
};

const items: TodoItem[] = [
  // ── PHASE 0: LOCAL SKELETON ──
  {
    id: 'P0-B1',
    title: 'Player identity & connection',
    phase: '0',
    layer: 'backend',
    status: 'done',
    desc: 'Player table, connectPlayer, renamePlayer, ping reducers. Auth token persistence.',
    files: 'services/spacetimedb/src/index.ts:143-218',
  },
  {
    id: 'P0-B2',
    title: 'World seeding (single system)',
    phase: '0',
    layer: 'backend',
    status: 'done',
    desc: 'seedWorld creates Solace system, station, 2 POIs. Hardcoded constants.',
    files: 'services/spacetimedb/src/index.ts:138-141, 458-500',
  },
  {
    id: 'P0-B3',
    title: 'Ship state & wallet',
    phase: '0',
    layer: 'backend',
    status: 'done',
    desc: 'Ship table (position, flightMode, dockedStationId, cargoCapacity). Wallet table with ISK.',
    files: 'services/spacetimedb/src/index.ts:28-45, 93-100',
  },
  {
    id: 'P0-B4',
    title: 'Server event logging',
    phase: '0',
    layer: 'backend',
    status: 'done',
    desc: 'ServerEvent table. Every reducer writes a typed event.',
    files: 'services/spacetimedb/src/index.ts:114-123, 580-588',
  },
  {
    id: 'P0-F1',
    title: 'SpacetimeDB client connection',
    phase: '0',
    layer: 'frontend',
    status: 'done',
    desc: 'Connection lifecycle, table subscriptions, auth token, re-render triggers.',
    files: 'apps/game/src/spacetime/client.ts, useSpacetimeConnection.ts, useGameSession.ts',
  },
  {
    id: 'P0-F2',
    title: 'Game shell layout',
    phase: '0',
    layer: 'frontend',
    status: 'partial',
    desc: 'Three-column responsive layout with left/right sidebars and center 3D viewport. Missing: center panel area is empty (hidden on large screens). No loading/splash screen.',
    detail: 'Middle column <section> is hidden lg:block with no content. No station mode panel swap. Inline "Pilot" info should be its own component.',
    files: 'apps/game/src/GameShell.tsx:70',
  },
  {
    id: 'P0-F3',
    title: 'Connection panel',
    phase: '0',
    layer: 'frontend',
    status: 'done',
    desc: 'Connection status, identity, transport/reducer messages, pilot name input, rename/ping.',
    files: 'apps/game/src/ui/ConnectionPanel.tsx',
  },
  {
    id: 'P0-S1',
    title: '3D space scene foundation',
    phase: '0',
    layer: 'scene',
    status: 'partial',
    desc: 'R3F Canvas, environment (stars, fog, lights), station mesh, asteroid mesh, ship mesh. All clickable.',
    detail: 'Missing: camera controls (no orbit/zoom/pan — fixed position). No sun/star light source. No nebulae. Grid plane is debug-only.',
    files: 'apps/game/src/scene/',
  },
  {
    id: 'P0-S2',
    title: 'Ship mesh with engine glow',
    phase: '0',
    layer: 'scene',
    status: 'partial',
    desc: 'Cone+box+sphere ship. Engine glow changes by flightMode. Bob/roll animation.',
    detail: 'Missing: no damage state visualization, no shield bubble, no warp animation, no mining laser beam (only flat Line), no module hardpoints visible.',
    files: 'apps/game/src/scene/ShipMesh.tsx',
  },

  // ── PHASE 1: NAVIGATION & EXPLORATION ──
  {
    id: 'P1-B1',
    title: 'Approach operation (start + complete)',
    phase: '1',
    layer: 'backend',
    status: 'done',
    desc: 'Timed approach with 5s duration. Validates undocked, target selected, target in system. Position update on complete.',
    files: 'services/spacetimedb/src/index.ts:248-299',
  },
  {
    id: 'P1-B2',
    title: 'Target selection',
    phase: '1',
    layer: 'backend',
    status: 'done',
    desc: 'selectTarget validates POI exists and is in current system.',
    files: 'services/spacetimedb/src/index.ts:236-246',
  },
  {
    id: 'P1-B3',
    title: 'Warp travel between systems',
    phase: '1',
    layer: 'backend',
    status: 'missing',
    desc: 'No stargate table, no warp sequence, no jump mechanics. Ship is locked to single system (Solace).',
    blockedBy: ['P5-B3'],
  },
  {
    id: 'P1-B4',
    title: 'Stargate network',
    phase: '1',
    layer: 'backend',
    status: 'missing',
    desc: 'No stargate table. No gate activation range, jump cooldown, gate cloak. Design describes full stargate mechanics.',
  },
  {
    id: 'P1-F1',
    title: 'Mini star map (SVG)',
    phase: '1',
    layer: 'frontend',
    status: 'done',
    desc: '2D SVG top-down system map showing POIs, ship position, operation lines, click-to-select.',
    files: 'apps/game/src/ui/MiniStarMap.tsx',
  },
  {
    id: 'P1-F2',
    title: 'Target panel with POI list',
    phase: '1',
    layer: 'frontend',
    status: 'partial',
    desc: 'Shows selected target and clickable POI list.',
    detail: 'Missing: no distance to target, no spatial grouping, no range info, no sortable overview-style list.',
    files: 'apps/game/src/ui/TargetPanel.tsx',
  },
  {
    id: 'P1-F3',
    title: 'Command rail (contextual actions)',
    phase: '1',
    layer: 'frontend',
    status: 'partial',
    desc: 'Bottom-fixed action bar with contextual buttons and progress bars for operations.',
    detail: 'Missing: no abort/cancel operation, no warp/jump commands, no combat commands, no station service buttons, keyboard shortcut hints not visible.',
    files: 'apps/game/src/ui/CommandRail.tsx',
  },
  {
    id: 'P1-F4',
    title: 'Keyboard shortcuts',
    phase: '1',
    layer: 'frontend',
    status: 'partial',
    desc: 'U=undock, D=dock, A=approach, M=mine, 1-9=select target.',
    detail: 'Missing: no shortcut for sell, refine, fit, combat, warp. No modifier keys. No shortcut discovery overlay.',
    files: 'apps/game/src/ui/useKeyboardShortcuts.ts',
  },
  {
    id: 'P1-S1',
    title: 'Ship position interpolation during approach',
    phase: '1',
    layer: 'scene',
    status: 'done',
    desc: 'Lerp-based smooth movement from current position to target during approach operation.',
    files: 'apps/game/src/scene/GameSpaceScene.tsx',
  },
  {
    id: 'P1-S2',
    title: 'Camera controls (orbit, zoom, pan)',
    phase: '1',
    layer: 'scene',
    status: 'missing',
    desc: 'Camera is fixed at [8,9,44] with gentle sine drift. No OrbitControls, no zoom, no user camera interaction.',
  },
  {
    id: 'P1-S3',
    title: 'Warp/travel visual effects',
    phase: '1',
    layer: 'scene',
    status: 'missing',
    desc: 'No warp tunnel effect, no gate jump animation, no system transition. Prototype has a full warp sequence demo.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/WarpTravelDemo.tsx',
  },

  // ── PHASE 2: MINING, INVENTORY & TRADE ──
  {
    id: 'P2-B1',
    title: 'Mining operation (start + complete)',
    phase: '2',
    layer: 'backend',
    status: 'done',
    desc: 'Timed mining with 6s duration. Validates undocked, at asteroid belt, cargo not full. Adds 1000 Veldspar to cargo.',
    files: 'services/spacetimedb/src/index.ts:326-409',
  },
  {
    id: 'P2-B2',
    title: 'Cargo/inventory system',
    phase: '2',
    layer: 'backend',
    status: 'partial',
    desc: 'CargoItem table with stacking. Capacity tracking.',
    detail: 'Missing: only "ore" category used. No mineral, module, loot, commodity categories. No jettison. No item splitting.',
    files: 'services/spacetimedb/src/index.ts:79-91',
  },
  {
    id: 'P2-B3',
    title: 'NPC ore market (sell only)',
    phase: '2',
    layer: 'backend',
    status: 'partial',
    desc: 'sellOreToNpcMarket validates docked, ore category, quantity. Credits wallet.',
    detail: 'Missing: only 1 ore type (Veldspar) at fixed 12 ISK. No NPC buy orders for minerals/modules. No sell-side NPC. No dynamic pricing. No regional variation. Prices hardcoded in both backend AND frontend.',
    files: 'services/spacetimedb/src/index.ts:411-456',
  },
  {
    id: 'P2-B4',
    title: 'Dynamic NPC pricing (supply/demand)',
    phase: '2',
    layer: 'backend',
    status: 'missing',
    desc: 'Design describes full NPC pricing algorithm with EMA, demand pressure, regional seeds, anti-arbitrage. Nothing implemented.',
  },
  {
    id: 'P2-B5',
    title: 'Regional price differences',
    phase: '2',
    layer: 'backend',
    status: 'missing',
    desc: 'Single system only. No way for prices to differ between stations.',
    blockedBy: ['P1-B3', 'P5-B3'],
  },
  {
    id: 'P2-F1',
    title: 'Cargo panel',
    phase: '2',
    layer: 'frontend',
    status: 'partial',
    desc: 'Displays cargo items with name, quantity, category, unit price.',
    detail: 'Missing: no jettison button, no item stacking/splitting, no item details, no ore-type filtering.',
    files: 'apps/game/src/ui/CargoPanel.tsx',
  },
  {
    id: 'P2-F2',
    title: 'NPC market panel',
    phase: '2',
    layer: 'frontend',
    status: 'partial',
    desc: 'Sell ore UI with quantity input, max button, payout preview. Only visible when docked.',
    detail: 'Missing: only Veldspar. Prices hardcoded client-side in NPC_PRICES constant. No buy orders, no order book, no price history, no charts.',
    files: 'apps/game/src/ui/NpcMarketPanel.tsx:5-7',
  },
  {
    id: 'P2-F3',
    title: 'Wallet panel',
    phase: '2',
    layer: 'frontend',
    status: 'partial',
    desc: 'Shows ISK balance.',
    detail: 'Missing: no transaction history, no income/expenditure breakdown.',
    files: 'apps/game/src/ui/WalletPanel.tsx',
  },
  {
    id: 'P2-F4',
    title: 'Ship status panel',
    phase: '2',
    layer: 'frontend',
    status: 'partial',
    desc: 'Flight mode badge, hull/shield/speed bars, position, system, operation countdown.',
    detail: 'HARDCODED: hullPct=100 always (line 44), shieldPct=Math.random() (line 45), cargoPct always 0 (line 46), speed labels are hardcoded strings (lines 32-42). No armor layer. No capacitor. No power allocation. No module activation indicators.',
    files: 'apps/game/src/ui/ShipStatusPanel.tsx:44-46',
  },
  {
    id: 'P2-S1',
    title: 'Asteroid rendering (per-belt clusters)',
    phase: '2',
    layer: 'scene',
    status: 'partial',
    desc: '3 asteroids per belt with hardcoded offsets, tumble animation, clickable.',
    detail: 'Missing: all identical geometry/color. No ore type differentiation. No depletion state. No mining laser beam (flat Line only).',
    files: 'apps/game/src/scene/AsteroidMesh.tsx, GameSpaceScene.tsx:120-124',
  },
  {
    id: 'P2-S2',
    title: 'Mining laser beam visual',
    phase: '2',
    layer: 'scene',
    status: 'missing',
    desc: 'Only a flat amber Line drawn during mining. No beam/particle effect connecting ship to asteroid.',
  },

  // ── PHASE 3: COMBAT — FTL POWER ALLOCATION ──
  {
    id: 'P3-B1',
    title: 'NPC pirate entity system',
    phase: '3',
    layer: 'backend',
    status: 'missing',
    desc: 'No npc_entities, npc_class_templates, or loot_tables. Design describes full NPC spawning, AI behavior, state machine (IDLE→AGGRO→COMBAT→FLEE→DEAD).',
  },
  {
    id: 'P3-B2',
    title: 'Combat encounter state',
    phase: '3',
    layer: 'backend',
    status: 'missing',
    desc: 'No combat session, no damage resolution, no shield/armor/hull tracking, no weapon cycling.',
  },
  {
    id: 'P3-B3',
    title: 'FTL power allocation (weapons/shields/engines/aux)',
    phase: '3',
    layer: 'backend',
    status: 'missing',
    desc: 'Design describes 4 subsystems with powered/unpowered behavior, reroute timing (1.5-3s), and failure modes. Nothing implemented.',
  },
  {
    id: 'P3-B4',
    title: 'Ship health model (shield/armor/hull)',
    phase: '3',
    layer: 'backend',
    status: 'missing',
    desc: 'Ship table has no health columns. Design describes 3 HP pools with different damage resistance.',
  },
  {
    id: 'P3-B5',
    title: 'Bounty & loot drop system',
    phase: '3',
    layer: 'backend',
    status: 'missing',
    desc: 'No bounty ISK awards, no loot tables, no wreck/loot containers. Design describes full bounty tiers and module drops.',
  },
  {
    id: 'P3-B6',
    title: 'Ship destruction & respawn',
    phase: '3',
    layer: 'backend',
    status: 'missing',
    desc: 'No death mechanic, no respawn, no insurance payout. Design describes rookie frigate respawn, loot drops, insurance.',
  },
  {
    id: 'P3-F1',
    title: 'Combat HUD (target lock, power allocation, damage)',
    phase: '3',
    layer: 'frontend',
    status: 'missing',
    desc: 'No combat UI at all. Design describes target lock reticle, power allocation bars (W/S/E/Aux), shield/armor/hull wheel, capacitor gauge, weapon timer, combat log.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/CombatDemo.tsx, game-slice/ui/SliceCombatStage.tsx',
  },
  {
    id: 'P3-S1',
    title: 'Combat 3D scene (projectiles, shields, explosions)',
    phase: '3',
    layer: 'scene',
    status: 'missing',
    desc: 'No NPC ships rendered, no projectiles, no shield effects, no explosions, no damage numbers.',
    files: 'Prototype ref: apps/docs/src/prototypes/r3f/combat/CombatScene.tsx',
  },

  // ── PHASE 4: SHIP CUSTOMIZATION & UPGRADES ──
  {
    id: 'P4-B1',
    title: 'Ship types catalog (multiple classes)',
    phase: '4',
    layer: 'backend',
    status: 'missing',
    desc: 'Only 1 hardcoded "Starter Frigate". Design describes 5 classes (Frigate through Battleship) with full stat tables.',
  },
  {
    id: 'P4-B2',
    title: 'Module catalog & fitting system',
    phase: '4',
    layer: 'backend',
    status: 'missing',
    desc: 'No modules_catalog, no ship_fittings table. Design describes High/Med/Low slot types, CPU/PG constraints, module categories.',
  },
  {
    id: 'P4-B3',
    title: 'Fit/unfit module reducers',
    phase: '4',
    layer: 'backend',
    status: 'missing',
    desc: 'No reducers for module management. Design validates CPU/PG budget, slot type matching.',
  },
  {
    id: 'P4-B4',
    title: 'Ship purchase/acquisition',
    phase: '4',
    layer: 'backend',
    status: 'missing',
    desc: 'No ship buying, no hangar storage, no ship switching. Design describes NPC market, hangar, and rookie frigate policy.',
  },
  {
    id: 'P4-F1',
    title: 'Fitting screen UI',
    phase: '4',
    layer: 'frontend',
    status: 'missing',
    desc: 'No fitting UI. Design describes slot layout with drag-and-drop, CPU/PG bars, module catalog.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/FittingDemo.tsx, game-slice/ui/SliceFittingService.tsx',
  },
  {
    id: 'P4-F2',
    title: 'Ship purchase screen',
    phase: '4',
    layer: 'frontend',
    status: 'missing',
    desc: 'No ship shop, no hangar view, no ship comparison UI.',
  },

  // ── PHASE 5: FACTION QUESTS & DYNAMIC WORLD ──
  {
    id: 'P5-B1',
    title: 'Faction & standing system',
    phase: '5',
    layer: 'backend',
    status: 'missing',
    desc: 'No factions table, no player standing, no loyalty points. Design describes -10 to +10 standing with faction consequences.',
  },
  {
    id: 'P5-B2',
    title: 'NPC agents & mission templates',
    phase: '5',
    layer: 'backend',
    status: 'missing',
    desc: 'No npc_agents, mission_templates, active_missions tables. Design describes 6 mission types (kill, courier, mining, survey, escort, trade) with 4 reward tiers.',
  },
  {
    id: 'P5-B3',
    title: 'Procedural galaxy generation',
    phase: '5',
    layer: 'backend',
    status: 'missing',
    desc: 'Single hardcoded system (Solace). Design describes seeded RNG galaxy with MST stargate topology, regions, constellations.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/GalaxyDemo.tsx',
  },
  {
    id: 'P5-B4',
    title: 'Station prosperity (dynamic world impact)',
    phase: '5',
    layer: 'backend',
    status: 'missing',
    desc: 'No station prosperity, no resource demand model. Design describes stations growing when supplied, faction leaders taking provinces.',
  },
  {
    id: 'P5-B5',
    title: 'World events (anomalies, faction conflicts)',
    phase: '5',
    layer: 'backend',
    status: 'missing',
    desc: 'No event spawning, no participation tracking, no galaxy story log. Design describes 6 event categories with 3 notification tiers.',
  },
  {
    id: 'P5-F1',
    title: 'Agent/mission panel',
    phase: '5',
    layer: 'frontend',
    status: 'missing',
    desc: 'No NPC agent list, no available missions, no mission tracker, no standing display.',
  },
  {
    id: 'P5-F2',
    title: 'Galaxy map (multi-system)',
    phase: '5',
    layer: 'frontend',
    status: 'missing',
    desc: 'Only single-system SVG map exists. No multi-system navigation, no stargate routes, no faction overlay.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/StarMapDemo.tsx',
  },

  // ── PHASE 6: INDUSTRY & ECONOMY DEPTH ──
  {
    id: 'P6-B1',
    title: 'Refining (ore → minerals)',
    phase: '6',
    layer: 'backend',
    status: 'missing',
    desc: 'No refineOre reducer, no mineral item types. Design describes 8 ore types refining to 8 minerals with skill-based yield (50-95%).',
    files: 'Prototype ref: apps/docs/src/prototypes/game-slice/sliceEconomy.ts',
  },
  {
    id: 'P6-B2',
    title: 'Manufacturing (minerals → modules/ships)',
    phase: '6',
    layer: 'backend',
    status: 'missing',
    desc: 'No blueprints, no manufacturing_jobs, no production chain. Design describes 5-tier chain: Ore → Mineral → Component → Module → Ship.',
  },
  {
    id: 'P6-B3',
    title: 'Multiple ore types',
    phase: '6',
    layer: 'backend',
    status: 'missing',
    desc: 'Only Veldspar. Design describes 8 ore types (Veldspar, Scordite, Pyroxeres, Kernite, Omber, Jaspet, Hemorphite, Arkonor).',
  },
  {
    id: 'P6-F1',
    title: 'Refining UI',
    phase: '6',
    layer: 'frontend',
    status: 'missing',
    desc: 'No refining interface. Design describes batch processing with yield preview.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/RefiningDemo.tsx, game-slice/ui/SliceRefiningService.tsx',
  },
  {
    id: 'P6-F2',
    title: 'Manufacturing UI',
    phase: '6',
    layer: 'frontend',
    status: 'missing',
    desc: 'No manufacturing tab. Design describes blueprint selection, job queue, material requirements.',
  },
  {
    id: 'P6-F3',
    title: 'Market with order book & price history',
    phase: '6',
    layer: 'frontend',
    status: 'missing',
    desc: 'No order book, no charts, no bid/ask spread. Only flat NPC buy for ore.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/MarketDemo.tsx',
  },

  // ── PHASE 7: POLISH & PROCEDURAL GALAXY ──
  {
    id: 'P7-B1',
    title: 'XP & skill progression',
    phase: '7',
    layer: 'backend',
    status: 'missing',
    desc: 'No skills_catalog, no XP awards. Design describes 5 skills (Mining, Industry, Trade, Gunnery, Navigation) with level 0-5.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/ProgressionDemo.tsx',
  },
  {
    id: 'P7-B2',
    title: 'Tutorial objective chain',
    phase: '7',
    layer: 'backend',
    status: 'missing',
    desc: 'No objective tracking. Prototype has 7-objective tutorial chain.',
    files: 'Prototype ref: apps/docs/src/prototypes/game-slice/sliceObjectives.ts',
  },
  {
    id: 'P7-B3',
    title: 'Zora ship AI (Tier 0)',
    phase: '7',
    layer: 'backend',
    status: 'missing',
    desc: 'No Zora state, no soul depth, no personality axes, no module gating.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/ZoraDemo.tsx',
  },
  {
    id: 'P7-B4',
    title: 'CONCORD / law enforcement',
    phase: '7',
    layer: 'backend',
    status: 'missing',
    desc: 'No security status, no CONCORD response, no criminal flagging.',
  },
  {
    id: 'P7-B5',
    title: 'Insurance system',
    phase: '7',
    layer: 'backend',
    status: 'missing',
    desc: 'No insurance policies, no coverage tiers, no payout on death.',
  },
  {
    id: 'P7-F1',
    title: 'Tutorial / onboarding flow',
    phase: '7',
    layer: 'frontend',
    status: 'missing',
    desc: 'No guided mission sequence, no skip option, no Zora hints.',
  },
  {
    id: 'P7-F2',
    title: 'Full Flight Mode HUD (diegetic)',
    phase: '7',
    layer: 'frontend',
    status: 'missing',
    desc: 'No diegetic HUD overlays on 3D viewport. Design describes curved shield/armor bars, module rack, overview panel, targeting reticle, capacitor gauge.',
    files: 'Prototype ref: apps/docs/src/prototypes/existing-demos/GameHudDemo.tsx',
  },
  {
    id: 'P7-F3',
    title: 'Station Mode panel UI',
    phase: '7',
    layer: 'frontend',
    status: 'missing',
    desc: 'No station service menu. No docked-mode panel swap. GameShell shows same panels regardless of dock/flight state.',
  },
  {
    id: 'P7-F4',
    title: 'Event feed with categories',
    phase: '7',
    layer: 'frontend',
    status: 'partial',
    desc: 'Basic event log exists (12 items, no pagination).',
    detail: 'Missing: no color coding by event type, no filtering, no combat vs market vs system categorization, no click-to-zoom.',
    files: 'apps/game/src/ui/EventFeed.tsx',
  },
  {
    id: 'P7-F5',
    title: 'Fog of war / map reveal',
    phase: '7',
    layer: 'frontend',
    status: 'missing',
    desc: 'No fog of war mechanic. All POIs visible immediately in current system.',
  },

  // ── CROSS-CUTTING / INFRASTRUCTURE ──
  {
    id: 'X-B1',
    title: 'Scheduled agents (timed server logic)',
    phase: '0',
    layer: 'backend',
    status: 'missing',
    desc: 'All game logic is reducer-call driven. No timed agents for: NPC spawning, combat ticks, economy ticks, world events, balancing.',
  },
  {
    id: 'X-F1',
    title: 'Hardcoded system/station references',
    phase: '1',
    layer: 'frontend',
    status: 'partial',
    desc: 'Client subscribes to hardcoded "solace" system and "solace-prime" station. useGameSession hardcodes these lookups.',
    detail: 'client.ts:77-78, useGameSession.ts:129-130. Must be replaced with dynamic system lookup once multi-system exists.',
    files: 'apps/game/src/spacetime/client.ts:77-78',
  },
  {
    id: 'X-F2',
    title: 'Operation auto-completion (client polling)',
    phase: '1',
    layer: 'frontend',
    status: 'partial',
    desc: 'GameSpaceScene polls Date.now() at 120ms intervals to detect operation completion and fire completeApproach/completeMiningCycle.',
    detail: 'Works but is client-driven. Design recommends server-authoritative completion via scheduled reducers.',
    files: 'apps/game/src/scene/GameSpaceScene.tsx',
  },
  {
    id: 'X-F3',
    title: 'Ambient traffic / other entities',
    phase: '2',
    layer: 'frontend',
    status: 'missing',
    desc: 'No other ships visible in space. Prototype has 4 ambient entities (3 friendly + 1 hostile) with orbital movement.',
    files: 'Prototype ref: apps/docs/src/prototypes/game-slice/ui/SliceFlightStage.tsx:78-92',
  },
];

const PHASE_LABELS: Record<Phase, string> = {
  '0': 'Phase 0 — Local Skeleton',
  '1': 'Phase 1 — Navigation & Exploration',
  '2': 'Phase 2 — Mining, Inventory & Trade',
  '3': 'Phase 3 — Combat (FTL Power Allocation)',
  '4': 'Phase 4 — Ship Customization & Upgrades',
  '5': 'Phase 5 — Faction Quests & Dynamic World',
  '6': 'Phase 6 — Industry & Economy Depth',
  '7': 'Phase 7 — Polish & Procedural Galaxy',
};

export function TodoPage() {
  const [filterPhase, setFilterPhase] = useState<string>('all');
  const [filterLayer, setFilterLayer] = useState<string>('all');
  const [filterStatus, setFilterStatus] = useState<string>('all');

  const filtered = useMemo(() => {
    return items.filter(item => {
      if (filterPhase !== 'all' && item.phase !== filterPhase) return false;
      if (filterLayer !== 'all' && item.layer !== filterLayer) return false;
      if (filterStatus !== 'all' && item.status !== filterStatus) return false;
      return true;
    });
  }, [filterPhase, filterLayer, filterStatus]);

  const counts = useMemo(() => {
    const byStatus = { done: 0, partial: 0, missing: 0, blocked: 0 };
    const byPhase: Record<string, { done: number; partial: number; missing: number; blocked: number; total: number }> = {};
    items.forEach(item => {
      byStatus[item.status]++;
      if (!byPhase[item.phase]) byPhase[item.phase] = { done: 0, partial: 0, missing: 0, blocked: 0, total: 0 };
      byPhase[item.phase][item.status]++;
      byPhase[item.phase].total++;
    });
    return { byStatus, byPhase };
  }, []);

  const grouped = useMemo(() => {
    const groups: Record<string, TodoItem[]> = {};
    filtered.forEach(item => {
      const key = item.phase === '0' && item.id.startsWith('X-') ? 'cross' : item.phase;
      if (!groups[key]) groups[key] = [];
      groups[key].push(item);
    });
    return groups;
  }, [filtered]);

  const phaseOrder = ['0', '1', '2', '3', '4', '5', '6', '7', 'cross'];
  const sortedGroups = phaseOrder.filter(p => grouped[p]).map(p => ({
    key: p,
    label: p === 'cross' ? 'Cross-Cutting / Infrastructure' : PHASE_LABELS[p as Phase],
    items: grouped[p],
  }));

  return (
    <div className="mx-auto max-w-content">
      <h1 style={{ marginBottom: '8px' }}>Implementation Status</h1>
      <p style={{ color: 'var(--fg-dim)', fontSize: '0.95rem', maxWidth: '720px' }}>
        Living TODO document tracking what's built vs. what's designed. Auto-generated from codebase review on {LAST_UPDATED}.
        Each item maps to a specific phase, layer, and file reference.
      </p>

      <div className="mb-6 grid grid-cols-[repeat(auto-fit,minmax(150px,1fr))] gap-4" style={{ marginTop: 'var(--sp-5)' }}>
        <div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
          <div className="font-mono text-[1.6rem] font-bold tabular-nums" style={{ color: 'var(--green)' }}>{counts.byStatus.done}</div>
          <div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Done</div>
        </div>
        <div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
          <div className="font-mono text-[1.6rem] font-bold tabular-nums" style={{ color: 'var(--accent)' }}>{counts.byStatus.partial}</div>
          <div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Partial</div>
        </div>
        <div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
          <div className="font-mono text-[1.6rem] font-bold tabular-nums" style={{ color: 'var(--red)' }}>{counts.byStatus.missing}</div>
          <div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Missing</div>
        </div>
        <div className="rounded-xl border border-border bg-surface p-5 max-md:rounded-lg max-md:p-4">
          <div className="font-mono text-[1.6rem] font-bold tabular-nums" style={{ color: 'var(--muted)' }}>{counts.byStatus.blocked}</div>
          <div className="mt-1 text-[0.75rem] uppercase tracking-[0.05em] text-muted">Blocked</div>
        </div>
      </div>

      <div className="mb-6 rounded-lg px-5 py-4 text-[0.85rem] leading-[1.5] border border-cyan/20 bg-cyan/8 text-cyan">
        <strong>Backend coverage:</strong> {BACKEND_TABLES_IMPLEMENTED} / {BACKEND_TABLES_DESIGNED} tables ({Math.round(BACKEND_TABLES_IMPLEMENTED / BACKEND_TABLES_DESIGNED * 100)}%).
        {BACKEND_REDUCERS_IMPLEMENTED} / {BACKEND_REDUCERS_DESIGNED} reducers ({Math.round(BACKEND_REDUCERS_IMPLEMENTED / BACKEND_REDUCERS_DESIGNED * 100)}%).
        All 14 interactive demos and the full game-slice prototype live in <code>apps/docs/src/prototypes/</code> using localStorage — these serve as reference implementations for migration into the SpacetimeDB backend.
      </div>

      <div style={{ display: 'flex', gap: 'var(--sp-2)', marginBottom: 'var(--sp-6)', flexWrap: 'wrap' }}>
        <select
          value={filterPhase}
          onChange={e => setFilterPhase(e.target.value)}
          className="rounded-lg border border-border bg-surface-raised px-3 py-1.5 font-mono text-[0.75rem] text-fg"
        >
          <option value="all">All Phases</option>
          {Object.entries(PHASE_LABELS).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
          <option value="cross">Cross-Cutting</option>
        </select>
        <select
          value={filterLayer}
          onChange={e => setFilterLayer(e.target.value)}
          className="rounded-lg border border-border bg-surface-raised px-3 py-1.5 font-mono text-[0.75rem] text-fg"
        >
          <option value="all">All Layers</option>
          {Object.entries(LAYER_LABELS).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
        </select>
        <select
          value={filterStatus}
          onChange={e => setFilterStatus(e.target.value)}
          className="rounded-lg border border-border bg-surface-raised px-3 py-1.5 font-mono text-[0.75rem] text-fg"
        >
          <option value="all">All Status</option>
          {Object.entries(STATUS_LABELS).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
        </select>
        <span style={{ color: 'var(--muted)', fontSize: '0.75rem', lineHeight: '2' }}>
          {filtered.length} / {items.length} items
        </span>
      </div>

      {sortedGroups.map(group => {
        const phaseCounts = group.key !== 'cross' ? counts.byPhase[group.key] : null;
        const donePct = phaseCounts ? Math.round(((phaseCounts.done + phaseCounts.partial * 0.5) / phaseCounts.total) * 100) : null;

        return (
          <div key={group.key} style={{ marginBottom: 'var(--sp-8)' }}>
            <div style={{
              display: 'flex',
              alignItems: 'center',
              gap: 'var(--sp-3)',
              marginBottom: 'var(--sp-4)',
              paddingBottom: 'var(--sp-2)',
              borderBottom: '2px solid var(--border)',
            }}>
              <h2 style={{ margin: 0, fontSize: '1rem', flex: 1 }}>{group.label}</h2>
              {phaseCounts && (
                <div style={{ display: 'flex', gap: 'var(--sp-3)', alignItems: 'center' }}>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--green)' }}>{phaseCounts.done} done</span>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--accent)' }}>{phaseCounts.partial} partial</span>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--red)' }}>{phaseCounts.missing + phaseCounts.blocked} missing</span>
                  <div style={{
                    width: '80px',
                    height: '6px',
                    borderRadius: '3px',
                    background: 'var(--surface-raised)',
                    overflow: 'hidden',
                  }}>
                    <div style={{
                      width: `${donePct}%`,
                      height: '100%',
                      borderRadius: '3px',
                      background: donePct > 70 ? 'var(--green)' : donePct > 30 ? 'var(--accent)' : 'var(--red)',
                    }} />
                  </div>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--fg-dim)' }}>{donePct}%</span>
                </div>
              )}
            </div>

            <div className="w-full border-collapse" style={{ overflowX: 'auto' }}>
              <table className="w-full border-collapse text-[0.85rem] max-md:block max-md:overflow-x-auto max-md:rounded-lg max-md:border max-md:border-border max-md:[&_thead]:table max-md:[&_tbody]:table max-md:[&_thead]:min-w-[680px] max-md:[&_tbody]:min-w-[680px] [&_th]:whitespace-nowrap [&_th]:border-b [&_th]:border-border [&_th]:px-4 [&_th]:py-3 [&_th]:text-left [&_th]:font-mono [&_th]:text-[0.7rem] [&_th]:uppercase [&_th]:tracking-[0.06em] [&_th]:text-muted [&_td]:border-b [&_td]:border-border [&_td]:px-4 [&_td]:py-3 [&_td]:font-mono [&_td]:text-[0.8rem] [&_td]:text-fg [&_tr:hover_td]:bg-surface-raised">
                <thead>
                  <tr>
                    <th>ID</th>
                    <th>Status</th>
                    <th>Layer</th>
                    <th>Title</th>
                    <th>Details</th>
                  </tr>
                </thead>
                <tbody>
                  {group.items.map(item => (
                    <tr key={item.id}>
                      <td style={{ color: 'var(--muted)', fontSize: '0.7rem' }}>{item.id}</td>
                      <td>
                        <span style={{
                          display: 'inline-flex',
                          alignItems: 'center',
                          gap: '4px',
                          padding: '2px 8px',
                          borderRadius: 'var(--radius-pill)',
                          fontSize: '0.65rem',
                          fontWeight: 600,
                          fontFamily: 'var(--font-mono)',
                          background: item.status === 'done' ? 'rgba(34,197,94,0.1)' : item.status === 'partial' ? 'rgba(240,160,48,0.1)' : item.status === 'blocked' ? 'var(--surface-raised)' : 'rgba(239,68,68,0.1)',
                          color: STATUS_COLORS[item.status],
                          border: `1px solid ${STATUS_COLORS[item.status]}33`,
                        }}>
                          {STATUS_LABELS[item.status]}
                        </span>
                      </td>
                      <td style={{ color: 'var(--fg-dim)', fontSize: '0.7rem' }}>{LAYER_LABELS[item.layer]}</td>
                      <td style={{ fontWeight: 500, fontFamily: 'var(--font-body)', color: 'var(--fg)' }}>{item.title}</td>
                      <td>
                        <div style={{ color: 'var(--fg-dim)', fontSize: '0.8rem', fontFamily: 'var(--font-body)' }}>{item.desc}</div>
                        {item.detail && (
                          <div style={{ color: 'var(--accent)', fontSize: '0.75rem', marginTop: '4px', padding: '4px 8px', background: 'rgba(240,160,48,0.06)', borderRadius: '4px', borderLeft: '2px solid var(--accent)' }}>
                            {item.detail}
                          </div>
                        )}
                        {item.files && (
                          <div style={{ color: 'var(--muted)', fontSize: '0.65rem', marginTop: '4px', fontFamily: 'var(--font-mono)' }}>
                            {item.files}
                          </div>
                        )}
                        {item.blockedBy && (
                          <div style={{ color: 'var(--muted)', fontSize: '0.65rem', marginTop: '4px' }}>
                            Blocked by: {item.blockedBy.join(', ')}
                          </div>
                        )}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        );
      })}
    </div>
  );
}
