/**
 * Routing engine types — M4-002 (condition types) and M4-003 (action types).
 *
 * These types are re-exported from `@mosaicstack/types` for shared use across packages.
 */

// ─── Classification primitives ───────────────────────────────────────────────

/** Category of work the agent is being asked to perform */
export type TaskType =
  | 'coding'
  | 'research'
  | 'summarization'
  | 'conversation'
  | 'analysis'
  | 'creative';

/** Estimated complexity of the task, used to bias toward cheaper or more capable models */
export type Complexity = 'simple' | 'moderate' | 'complex';

/** Primary knowledge domain of the task */
export type Domain = 'frontend' | 'backend' | 'devops' | 'docs' | 'general';

/**
 * Cost tier for model selection.
 * Extends the existing `CostTier` in `@mosaicstack/types` with `local` for self-hosted models.
 */
export type CostTier = 'cheap' | 'standard' | 'premium' | 'local';

/** Special model capability required by the task */
export type Capability = 'tools' | 'vision' | 'long-context' | 'reasoning' | 'embedding';

// ─── Condition types ─────────────────────────────────────────────────────────

/**
 * A single predicate that must be satisfied for a routing rule to match.
 *
 * - `eq`       — scalar equality: `field === value`
 * - `in`       — set membership: `value` contains `field`
 * - `includes` — array containment: `field` (array) includes `value`
 */
export interface RoutingCondition {
  /** The task-classification field to test */
  field: 'taskType' | 'complexity' | 'domain' | 'costTier' | 'requiredCapabilities';
  /** Comparison operator */
  operator: 'eq' | 'in' | 'includes';
  /** Expected value or set of values */
  value: string | string[];
}

// ─── Action types ────────────────────────────────────────────────────────────

/**
 * The routing action to execute when all conditions in a rule are satisfied.
 */
export interface RoutingAction {
  /** LLM provider identifier, e.g. `'anthropic'`, `'openai'`, `'ollama'` */
  provider: string;
  /** Model identifier, e.g. `'claude-opus-4-6'`, `'gpt-4o'` */
  model: string;
  /** Optional: use a specific pre-configured agent config from the agent registry */
  agentConfigId?: string;
  /** Optional: override the agent's default system prompt for this route */
  systemPromptOverride?: string;
  /** Optional: restrict the tool set available to the agent for this route */
  toolAllowlist?: string[];
}

// ─── Rule and decision types ─────────────────────────────────────────────────

/**
 * Full routing rule as stored in the database and used at runtime.
 */
export interface RoutingRule {
  /** UUID primary key */
  id: string;
  /** Human-readable rule name */
  name: string;
  /** Lower number = evaluated first; unique per scope */
  priority: number;
  /** `'system'` rules apply globally; `'user'` rules override for a specific user */
  scope: 'system' | 'user';
  /** Present only for `'user'`-scoped rules */
  userId?: string;
  /** All conditions must match for the rule to fire */
  conditions: RoutingCondition[];
  /** Action to take when all conditions are met */
  action: RoutingAction;
  /** Whether this rule is active */
  enabled: boolean;
}

/**
 * Structured representation of what an agent has been asked to do,
 * produced by the task classifier and consumed by the routing engine.
 */
export interface TaskClassification {
  taskType: TaskType;
  complexity: Complexity;
  domain: Domain;
  requiredCapabilities: Capability[];
}

/**
 * Output of the routing engine — which model to use and why.
 */
export interface RoutingDecision {
  /** LLM provider identifier */
  provider: string;
  /** Model identifier */
  model: string;
  /** Optional agent config to apply */
  agentConfigId?: string;
  /** Name of the rule that matched, for observability */
  ruleName: string;
  /** Human-readable explanation of why this rule was selected */
  reason: string;
}
