// Minimal types for the BooCoder frontend.
// Shared DB entities (same schema as BooChat).

export interface Project {
  id: string;
  name: string;
  path: string;
  status: 'open' | 'archived';
  created_at: string;
  updated_at: string;
}

export interface Session {
  id: string;
  project_id: string;
  name: string | null;
  model: string | null;
  status: 'open' | 'archived';
  created_at: string;
  updated_at: string;
}

export interface Chat {
  id: string;
  session_id: string;
  name: string | null;
  status: 'open' | 'archived';
  created_at: string;
  updated_at: string;
}

export interface ToolCall {
  id: string;
  name: string;
  args: unknown;
}

export interface ToolResult {
  tool_call_id: string;
  output: unknown;
  truncated?: boolean;
  error?: boolean;
}

// Batch 9.7: ask_user_input shapes. The tool_call.args is { questions: AskUserQuestion[] }
// (1-3 entries); the eventual tool_result.output is { answers: AskUserAnswer[] } in the
// same order. AskUserInputCard renders questions and POSTs answers.
export type AskUserQuestionType = 'single_select' | 'multi_select';

export interface AskUserQuestion {
  question: string;
  type: AskUserQuestionType;
  options: string[];
}

export interface AskUserAnswer {
  question: string;
  selected_options: string[];
  free_text: string | null;
}

export interface AskUserAnswerSet {
  answers: AskUserAnswer[];
}

export interface Message {
  id: string;
  session_id: string;
  chat_id: string;
  role: 'user' | 'assistant' | 'tool' | 'system';
  content: string;
  kind: string;
  tool_calls: ToolCall[] | null;
  tool_results: ToolResult | null;
  status: 'streaming' | 'complete' | 'failed' | 'cancelled';
  tokens_used: number | null;
  ctx_used: number | null;
  ctx_max: number | null;
  started_at: string | null;
  finished_at: string | null;
  created_at: string;
  metadata: unknown;
}

export interface PendingChange {
  id: string;
  session_id: string;
  task_id: string | null;
  file_path: string;
  operation: 'create' | 'edit' | 'delete';
  old_string: string | null;
  new_string: string | null;
  content: string | null;
  diff: string | null;
  status: 'pending' | 'applied' | 'rejected' | 'reverted';
  created_at: string;
  applied_at: string | null;
}

// WebSocket frame types (subset of what the coder backend publishes)
export type WsFrame =
  | { type: 'snapshot'; messages: Message[] }
  | { type: 'message_started'; message_id: string; chat_id: string; role: Message['role'] }
  | { type: 'delta'; message_id: string; chat_id: string; content: string }
  | { type: 'tool_call'; message_id: string; chat_id: string; tool_call: ToolCall }
  | { type: 'tool_result'; tool_message_id: string; chat_id: string; tool_call_id: string; output: string; truncated?: boolean; error?: boolean }
  | { type: 'message_complete'; message_id: string; chat_id: string; tokens_used?: number; ctx_used?: number; ctx_max?: number; started_at?: string; finished_at?: string; metadata?: unknown }
  | { type: 'error'; message_id?: string; error: string; reason?: string }
  | { type: 'pending_change_added'; change: PendingChange }
  | { type: 'pending_change_updated'; change: PendingChange };
