/**
 * Type definitions for Agent Chat configuration.
 *
 * These types support fully parameterized agent configuration,
 * enabling lib/ to be completely decoupled from agents/.
 */

import type {
  AgentRoutingConfig,
  ResponseTuningConfig,
} from '../../../lib/shared/schemas/agents';
import type { ToolName } from '../../agent_tools/tool_registry';
import type { AgentType } from '../context_management/constants';

/**
 * Serializable Agent configuration for creating agents.
 * All fields are JSON-serializable and can be passed through scheduler.
 */
export interface SerializableAgentConfig {
  /** Agent name identifier */
  name: string;
  /**
   * Root behavior. Omitted = 'chat'. When 'image-generation', the startAgentChat
   * helper routes to the direct image-gen action instead of runAgentGeneration.
   */
  primaryBehavior?: 'chat' | 'image-generation';
  /** System instructions for the agent (empty for image-generation agents with no style prefix) */
  instructions: string;
  /** List of Convex tool names to enable */
  convexToolNames?: ToolName[];
  /** Integration names bound as dedicated tools (resolved at runtime) */
  integrationBindings?: string[];
  /** Workflow root version IDs bound as dedicated tools (resolved at runtime) */
  workflowBindings?: string[];
  /** Explicit model override */
  model?: string;
  /** Explicit provider name (matches provider filename, e.g. 'openrouter') */
  provider?: string;
  /** Maximum number of steps for tool calls */
  maxSteps?: number;
  /** Output format (text or json) */
  outputFormat?: 'text' | 'json';
  /** Knowledge retrieval mode: tool (agent calls rag_search), context (auto-inject), both, or off */
  knowledgeMode?: 'off' | 'tool' | 'context' | 'both';
  /** Web search retrieval mode: tool (agent calls web), context (auto-inject), both, or off */
  webSearchMode?: 'off' | 'tool' | 'context' | 'both';
  /** Per-agent personalization injection mode: 'on' (default) or 'off' (strip user memory + customInstructions + propose_memory tool). Use 'off' for high-risk / regulated agents (GDPR Art 22 / EU AI Act). */
  personalizationMode?: 'on' | 'off';
  /** Whether to include team documents in knowledge scope (default true) */
  includeTeamKnowledge?: boolean;
  /** Whether to include org-wide documents in knowledge scope (default false) */
  includeOrgKnowledge?: boolean;
  /** Team ID the agent is assigned to (primary/legacy) */
  agentTeamId?: string;
  /** All team IDs the agent is scoped to (union of teamId + sharedWithTeamIds) */
  agentTeamIds?: string[];
  /** Pre-resolved completed file IDs from agent-specific knowledge files */
  knowledgeFileIds?: string[];
  /** Agent slugs of delegate agents (file-based agent names) */
  delegateSlugs?: string[];
  /**
   * Hard allowlist of skill slugs the agent may use. Empty / omitted = no
   * skills available; the runtime emits no `expand_skill` tool and no
   * "Available Skills" section in that case. `buildSkillContext` intersects
   * this list with the org's actual skills at turn start — stale slugs are
   * silently dropped.
   */
  skillBindings?: string[];
  /** Whether to inject structured response markers into the system prompt (default false) */
  structuredResponsesEnabled?: boolean;
  /** Per-agent timeout in milliseconds */
  timeoutMs?: number;
  /** Per-agent output token reserve */
  outputReserve?: number;
  /** Ordered fallback model IDs (tried in sequence when primary fails) */
  fallbackModels?: string[];
  /**
   * Per-agent response tuning (effort/creativity/style + governor bounds).
   * Consumed by `buildReasoningOptions` and the style/verbosity prompt
   * fragments. Mirrors `responseTuningSchema` in
   * `lib/shared/schemas/agents.ts`.
   */
  responseTuning?: ResponseTuningConfig;
  /**
   * Advisory reply-language hint set by the Auto router for this turn (BCP-47
   * code or language name). Feeds ONLY the response-language directive's
   * fallback (rule 3) for ambiguous input — the directive's explicit-request
   * (rule 1) and message-language (rule 2) rules still take precedence.
   * Unset for pinned agents and ambiguous messages.
   */
  replyLocaleHint?: string;
  /**
   * Per-agent routing / cascade behaviour. Mirrors `agentRoutingSchema`.
   * Consumed by the model-tier router and the speculative cascade.
   */
  routing?: AgentRoutingConfig;
}

/**
 * Hook configuration using FunctionHandle strings.
 * FunctionHandle is serializable and can be passed through scheduler.
 */
export interface AgentHooksConfig {
  /** FunctionHandle for beforeContext hook (mutation) */
  beforeContext?: string;
  /** FunctionHandle for beforeGenerate hook (mutation) */
  beforeGenerate?: string;
  /** FunctionHandle for afterGenerate hook (mutation) */
  afterGenerate?: string;
}

/**
 * Complete runtime configuration for starting an agent chat.
 * All fields are serializable and can be passed through scheduler.
 */
export interface AgentRuntimeConfig {
  /** Agent type identifier */
  agentType: AgentType;
  /** Serializable agent configuration */
  agentConfig: SerializableAgentConfig;
  /** Model to use for response generation */
  model: string;
  /** Model provider name (e.g., 'openrouter'). Omit to search all providers. */
  provider?: string;
  /** Debug tag for logging */
  debugTag: string;
  /** Enable streaming response */
  enableStreaming: boolean;
  /** Optional hooks configuration (FunctionHandles) */
  hooks?: AgentHooksConfig;
}

/**
 * Optional LLM generation parameters (temperature, etc.).
 * Only set fields that are explicitly provided; omit to use model defaults.
 */
export interface GenerationParams {
  temperature?: number;
  maxTokens?: number;
  topP?: number;
  frequencyPenalty?: number;
  presencePenalty?: number;
  stopSequences?: string[];
}

export interface RunAgentGenerationArgs {
  agentType: string;
  agentConfig: SerializableAgentConfig;
  model: string;
  provider?: string;
  debugTag: string;
  enableStreaming?: boolean;
  hooks?: AgentHooksConfig;
  threadId: string;
  organizationId: string;
  userId?: string;
  agentSlug?: string;
  promptMessage: string;
  additionalContext?: Record<string, string>;
  parentThreadId?: string;
  agentOptions?: unknown;
  attachments?: Array<{
    fileId: string;
    fileName: string;
    fileType: string;
    fileSize: number;
  }>;
  streamId?: string;
  promptMessageId?: string;
  maxSteps?: number;
  /** Optional per-request generation parameters from OpenAI compat endpoint */
  generationParams?: GenerationParams;
  /** Governance-enforced max context tokens (overrides agent config) */
  maxContextTokens?: number;
}

/**
 * Result from beforeContext hook.
 */
export interface BeforeContextHookResult {
  contextSummary?: string;
  [key: string]: unknown;
}

/**
 * Result from beforeGenerate hook.
 */
export interface BeforeGenerateHookResult {
  promptContent?: unknown;
  systemContextMessages?: unknown[];
  additionalContextData?: Record<string, unknown>;
}
