import type { ZodType, ZodTypeDef } from 'zod';

export type LlmProvider = 'anthropic' | 'openai-compatible';

export interface LlmConfig {
  enabled: boolean;
  provider: LlmProvider;
  model: string;
  /** Base URL without a trailing slash. Anthropic: https://api.anthropic.com.
   *  OpenAI-compatible: e.g. https://api.openai.com/v1, https://openrouter.ai/api/v1,
   *  http://localhost:11434/v1 (Ollama), http://localhost:1234/v1 (LM Studio). */
  baseUrl: string;
  apiKey: string;
  /** When false, the key is kept in memory only and never written to localStorage. */
  rememberKey: boolean;
}

export type LlmErrorKind =
  | 'disabled'
  | 'no-key'
  | 'timeout'
  | 'network'
  | 'csp'
  | 'http'
  | 'parse';

export type LlmResult<T> =
  | { ok: true; data: T }
  | { ok: true; text: string }
  | { ok: false; error: LlmErrorKind; message: string };

export interface CompleteOptions<T = unknown> {
  /** System prompt — must lead with the grounding/system constraint. */
  system: string;
  /** User message. */
  user: string;
  /** When provided, structured JSON output is requested and validated against it.
   *  Input is left open (`any`) so schemas using coerce/preprocess/transform — whose
   *  parsed input type differs from T — are accepted; T is pinned to the output. */
  schema?: ZodType<T, ZodTypeDef, any>;
  /** A short name describing the JSON shape (used by providers that require it). */
  schemaName?: string;
  signal?: AbortSignal;
  timeoutMs?: number;
  maxTokens?: number;
}
