import type { WorkspacePaneKind, WorkspaceTabKind, WorkspacePane, WorkspaceState, ClosedPaneEntry, MarkdownArtifactState, HtmlArtifactState, OrchestratorState } from './session-types.js';

// 'global' = /data/AGENTS.md (always-on), 'project' = per-project override at
// <root>/AGENTS.md. In-code builtins were retired; the seed file lives at
// /data/AGENTS.md.
export type AgentSource = 'global' | 'project';

export interface Agent {
  id: string;
  name: string;
  description: string;
  system_prompt: string;
  temperature: number;
  tools: string[];
  model: string | null;
  source: AgentSource;
  // per-agent tool-loop budget. null means resolve at runtime from the agent's
  // toolset (30 for all read-only, 10 otherwise) or 15 for raw chat with no
  // agent.
  max_tool_calls: number | null;
  // per-agent step cap for the outer inference loop. null means bounded only by
  // MAX_STEPS (200). 0 means "no tool calls allowed."
  steps: number | null;
}

export interface AgentParseError {
  agent_name: string;
  reason: string;
}

export interface AgentsResponse {
  agents: Agent[];
  errors: AgentParseError[];
}

export type PermissionKind = 'tool' | 'question' | 'plan' | 'elicitation';

export interface PermissionPrompt {
  taskId: string;
  kind?: PermissionKind;
  toolTitle?: string;
  input?: Record<string, unknown>;
  options: Array<{ optionId: string; label: string }>;
}

export interface CoderSendMessageBody {
  content: string;
  pane_id: string;
  chat_id?: string;
  provider?: string;
  model?: string;
  mode_id?: string;
  thinking_option_id?: string;
}

export interface CoderSendMessageResponse {
  user_message_id?: string;
  assistant_message_id?: string;
  task_id?: string;
  dispatched?: boolean;
}

export interface CoderMessageWire {
  id: string;
  role: 'user' | 'assistant' | 'system';
  content: string;
  status?: 'streaming' | 'complete' | 'failed';
  // model-attribution: which model produced this coder assistant message.
  model?: string | null;
  reasoning_text?: string;
  // Context-window fill for the ContextBar (claude SDK turn sets these from the
  // SDK's reported window; other agents omit them). Read via the Message cast.
  ctx_used?: number | null;
  ctx_max?: number | null;
  tool_calls?: Array<{
    id: string;
    function: { name: string; arguments: string };
  }>;
}

export interface CoderTaskDetail {
  id: string;
  state: 'pending' | 'running' | 'completed' | 'failed' | 'blocked' | 'cancelled';
  input: string;
  output_summary: string | null;
  agent: string | null;
  model: string | null;
  session_id: string | null;
}

export interface SidebarSession {
  id: string;
  name: string;
  model: string;
  updated_at: string;
  project_id: string;
}

export interface SidebarProject {
  id: string;
  name: string;
  path: string;
  gitea_remote: string | null;
  recent_sessions: SidebarSession[];
  total_sessions: number;
}

export interface SidebarResponse {
  projects: SidebarProject[];
}

// skill catalog row. Returned by GET /api/skills and consumed by the
// slash-command dropdown. `path` and `mtime` are exposed for debug surface
// (/api/skills) but the dropdown only renders name + description.
export interface Skill {
  name: string;
  description: string;
  path: string;
  mtime: number;
}

// 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[];
}

// tool traces: per-tool-call record returned by GET /api/chats/:id/traces.
export interface ToolTrace {
  id: string;
  session_id: string;
  chat_id: string;
  message_id: string | null;
  turn_number: number;
  tool_name: string;
  tool_input: Record<string, unknown>;
  tool_output: string | null;
  started_at: string;
  finished_at: string | null;
  latency_ms: number | null;
  tokens_used: number | null;
  cache_tokens: number | null;
  reasoning_tokens: number | null;
  error: string | null;
  outcome: string | null;
  created_at: string;
}

export interface ToolTraceResponse {
  data: ToolTrace[];
  total: number;
  limit: number;
  offset: number;
}

// Orchestrator run API types (returned by GET /api/coder/runs/:id).
export interface FlowRunRow {
  id: string;
  project_id: string;
  flow_name: string;
  band: 'small' | 'medium' | 'large';
  model: string;
  status: 'running' | 'completed' | 'failed' | 'cancelled';
  input: { question: string; band?: string; [key: string]: unknown };
  report: string | null;
  error: string | null;
  created_at: string;
  updated_at: string;
}

export interface FlowStepRow {
  id: string;
  run_id: string;
  step_id: string;
  kind: 'agent' | 'code';
  agent: string | null;
  status: 'pending' | 'running' | 'completed' | 'failed' | 'skipped' | 'cancelled';
  task_id: string | null;
  chat_id: string | null;
  session_id: string | null;
  input: string | null;
  output: string | null;
  error: string | null;
  created_at: string;
  updated_at: string;
}

// Re-export workspace types from session-types for backward compat.
export type {
  WorkspacePaneKind,
  WorkspaceTabKind,
  WorkspacePane,
  WorkspaceState,
  ClosedPaneEntry,
  MarkdownArtifactState,
  HtmlArtifactState,
  OrchestratorState,
};

// Re-export contract types belonging to the coder domain.
export type { ErrorReason, MessageMetadata, AgentSessionConfig } from '@boocode/contracts/message-metadata';
export type {
  ProviderModel,
  ProviderMode,
  ThinkingOption,
  ProviderSnapshotStatus,
  AgentCommand,
  ProviderSnapshotEntry,
} from '@boocode/contracts/provider-snapshot';
export type {
  ProviderOverride,
  CoderProvidersFile,
  ProviderConfigPatch,
} from '@boocode/contracts/provider-config';
