// Copyright 2026 CRMy Contributors
// SPDX-License-Identifier: Apache-2.0

import type { ProviderId } from '@crmy/shared';

/** Persisted agent config (one per tenant). */
export interface AgentConfig {
  id: string;
  tenant_id: string;
  enabled: boolean;
  provider: ProviderId;
  base_url: string;
  api_key_enc: string | null;
  model: string;
  system_prompt: string | null;
  max_tokens_per_turn: number;
  llm_timeout_ms: number;
  history_retention_days: number;
  can_write_objects: boolean;
  can_log_activities: boolean;
  can_create_assignments: boolean;
  auto_extract_context: boolean;
  auto_promote_signals: boolean;
  signal_auto_promote_threshold: number;
  signal_source_quality: Record<string, number>;
  backup_enabled: boolean;
  backup_provider: ProviderId | null;
  backup_base_url: string | null;
  backup_api_key_enc: string | null;
  backup_model: string | null;
}

/** A single message in a conversation. */
export interface ConversationMessage {
  role: 'system' | 'user' | 'assistant' | 'tool';
  content: string;
  /** Present when role === 'assistant' and the model invoked tools. */
  tool_calls?: ToolCallRecord[];
  /** Present when role === 'tool' — the result of a specific tool call. */
  tool_call_id?: string;
  tool_name?: string;
}

export interface ToolCallRecord {
  id: string;
  name: string;
  arguments: string; // JSON string
}

/** Persisted session row. */
export interface AgentSession {
  id: string;
  tenant_id: string;
  user_id: string;
  label: string | null;
  context_type: string | null;
  context_id: string | null;
  context_name: string | null;
  messages: ConversationMessage[];
  token_count: number;
  created_at: string;
  updated_at: string;
  active_turn?: AgentTurn | null;
  attachments?: AgentSessionAttachment[];
}

export type AgentTurnStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';

export interface AgentTurn {
  id: string;
  tenant_id: string;
  session_id: string;
  user_id: string;
  status: AgentTurnStatus;
  input_message: string;
  context_detail: string | null;
  error_message: string | null;
  final_label: string | null;
  worker_id: string | null;
  lease_expires_at: string | null;
  heartbeat_at: string | null;
  attempt_count: number;
  started_at: string | null;
  completed_at: string | null;
  cancelled_at: string | null;
  created_at: string;
  updated_at: string;
}

export interface AgentTurnEventRow {
  id: string;
  tenant_id: string;
  turn_id: string;
  event_index: number;
  event_type: AgentEvent['type'];
  payload: AgentEvent;
  created_at: string;
}

export type AgentAttachmentMode = 'active_context' | 'raw_context';
export type AgentAttachmentStatus = 'ready' | 'processing' | 'processed' | 'failed' | 'consumed';

export interface AgentSessionAttachment {
  id: string;
  tenant_id: string;
  session_id: string;
  user_id: string;
  filename: string;
  format: string | null;
  mode: AgentAttachmentMode;
  status: AgentAttachmentStatus;
  extracted_text: string | null;
  text_excerpt: string | null;
  truncated: boolean;
  raw_context_result: unknown | null;
  raw_context_source_id: string | null;
  consumed_turn_id: string | null;
  consumed_at: string | null;
  error_message: string | null;
  metadata: Record<string, unknown>;
  created_at: string;
  updated_at: string;
}

/** SSE events emitted during a chat turn. */
export type AgentEvent =
  | { type: 'delta'; content: string }
  /** Human-readable status line emitted immediately before tool execution.
   *  turn_id groups all tool calls from the same agent loop round so the UI
   *  can collapse them into a single collapsible "Working…" row. */
  | { type: 'tool_status'; id: string; name: string; status: string; turn_id: string }
  | { type: 'tool_call'; id: string; name: string; arguments: Record<string, unknown>; turn_id: string }
  | { type: 'tool_result'; id: string; name: string; result: unknown; is_error: boolean; turn_id: string }
  /** Extended reasoning block emitted when the model supports thinking (e.g. claude-3-7-sonnet).
   *  turn_id matches the tool calls that follow so the UI can associate reasoning with actions. */
  | { type: 'thinking'; content: string; turn_id: string }
  | { type: 'done'; session_id: string; label: string | null }
  | { type: 'error'; message: string };

/** Tool definition passed to providers (provider-agnostic shape). */
export interface AgentToolDef {
  name: string;
  description: string;
  parameters: Record<string, unknown>; // JSON Schema
}
