/**
 * Shared types for the unified MCP console.
 */

import type { McpTool, McpResource, McpPrompt, InitializeResult, McpSession } from './mcp-session.js';

// ── Traffic event types (mirrors mcplocal's TrafficEvent) ──

export type TrafficEventType =
  | 'client_request'
  | 'client_response'
  | 'client_notification'
  | 'upstream_request'
  | 'upstream_response'
  | 'session_created'
  | 'session_closed';

export interface ActiveSession {
  sessionId: string;
  projectName: string;
  startedAt: string;
}

// ── Timeline ──

export type EventLane = 'interactive' | 'observed';

export interface TimelineEvent {
  id: number;
  timestamp: Date;
  lane: EventLane;
  eventType: TrafficEventType;
  method?: string | undefined;
  projectName: string;
  sessionId: string;
  upstreamName?: string | undefined;
  body: unknown;
  durationMs?: number | undefined;
  correlationId?: string | undefined;
}

// ── Lane filter ──

export type LaneFilter = 'all' | 'interactive' | 'observed';

// ── Action area ──

export interface ReplayConfig {
  proxyModel: string;
  provider: string | null;
  llmModel: string | null;
}

export interface ReplayResult {
  content: string;
  durationMs: number;
  error?: string | undefined;
}

export interface ProxyModelDetails {
  name: string;
  source: 'built-in' | 'local';
  type?: 'pipeline' | 'plugin' | undefined;
  controller?: string | undefined;
  controllerConfig?: Record<string, unknown> | undefined;
  stages?: Array<{ type: string; config?: Record<string, unknown> }> | undefined;
  appliesTo?: string[] | undefined;
  cacheable?: boolean | undefined;
  hooks?: string[] | undefined;
  extends?: string[] | undefined;
  description?: string | undefined;
}

export interface SearchState {
  searchMode: boolean;
  searchQuery: string;
  searchMatches: number[];   // line indices matching query
  searchMatchIdx: number;    // current match index, -1 = none
}

export type ActionState =
  | { type: 'none' }
  | { type: 'detail'; eventIdx: number; scrollOffset: number; horizontalOffset: number } & SearchState
  | {
      type: 'provenance';
      clientEventIdx: number;
      upstreamEvent: TimelineEvent | null;
      scrollOffset: number;
      horizontalOffset: number;
      focusedPanel: 'client' | 'upstream' | 'parameters' | 'preview';
      replayConfig: ReplayConfig;
      replayResult: ReplayResult | null;
      replayRunning: boolean;
      editingUpstream: boolean;
      editedContent: string;
      parameterIdx: number; // 0=ProxyModel, 1=Provider, 2=Model, 3=Live, 4=Server
      proxyModelDetails: ProxyModelDetails | null;
      liveOverride: boolean;
      serverList: string[];
      serverOverrides: Record<string, string>;
      selectedServerIdx: number; // -1 = project-wide, 0+ = specific server
      serverPickerOpen: boolean;
      modelPickerOpen: boolean;
      modelPickerIdx: number;
    } & SearchState
  | { type: 'tool-input'; tool: McpTool; loading: boolean }
  | { type: 'tool-browser' }
  | { type: 'resource-browser' }
  | { type: 'prompt-browser' }
  | { type: 'raw-jsonrpc' };

// ── Console state ──

export interface UnifiedConsoleState {
  // Connection
  phase: 'connecting' | 'ready' | 'error';
  error: string | null;

  // Interactive session
  session: McpSession | null;
  gated: boolean;
  initResult: InitializeResult | null;
  tools: McpTool[];
  resources: McpResource[];
  prompts: McpPrompt[];

  // Observed traffic (SSE)
  sseConnected: boolean;
  observedSessions: ActiveSession[];

  // Session sidebar
  showSidebar: boolean;
  selectedSessionIdx: number; // -2 = "New Session", -1 = all sessions, 0+ = sessions
  sidebarMode: 'sessions' | 'project-picker';
  availableProjects: string[];
  activeProjectName: string | null;

  // Toolbar
  toolbarFocusIdx: number; // -1 = not focused, 0-3 = which item

  // Timeline
  events: TimelineEvent[];
  focusedEventIdx: number; // -1 = auto-scroll
  nextEventId: number;
  laneFilter: LaneFilter;

  // Action area
  action: ActionState;

  // ProxyModel / LLM options (for provenance preview)
  availableModels: string[];
  availableProviders: string[];
  availableLlms: string[];

}

export const MAX_TIMELINE_EVENTS = 10_000;
