import type {
  ActivatedStepSkill,
  ActivatedStepTool,
  OperationToolSet,
  ToolExecutor,
  ToolSource,
} from '@lobechat/context-engine';
import type {
  ChatToolPayload,
  SecurityBlacklistConfig,
  UserInterventionConfig,
} from '@lobechat/types';

import type { Cost, CostLimit, Usage } from './usage';

/**
 * Agent's serializable state.
 * This is the "passport" that can be persisted and transferred.
 */
export interface AgentState {
  /** Cumulative record of skills activated at step level */
  activatedStepSkills?: ActivatedStepSkill[];
  /** Cumulative record of tools activated at step level */
  activatedStepTools?: ActivatedStepTool[];
  /**
   * Current calculated cost for this session.
   * Updated after each billable operation.
   */
  cost: Cost;

  /**
   * Optional cost limits configuration.
   * If set, execution will stop when limits are exceeded.
   */
  costLimit?: CostLimit;
  // --- Metadata ---
  createdAt: string;
  error?: any;
  /**
   * When true, the agent is in force-finish mode (maxSteps exceeded).
   * Tools are allowed to complete, but the next LLM call will have tools stripped
   * and a summary prompt injected to produce a final text response.
   */
  forceFinish?: boolean;
  // --- Interruption Handling ---
  /**
   * When status is 'interrupted', this stores the interruption context
   * for potential resumption or cleanup.
   */
  interruption?: {
    /** Reason for interruption */
    reason: string;
    /** Timestamp when interruption occurred */
    interruptedAt: string;
    /** The instruction that was being executed when interrupted */
    interruptedInstruction?: any;
    /** Whether the interruption can be resumed */
    canResume: boolean;
  };
  lastModified: string;

  /**
   * Optional maximum number of steps allowed.
   * If set, execution will stop with error when exceeded.
   */
  maxSteps?: number;

  // --- Core Context ---
  messages: any[];

  // --- Extensible metadata ---
  metadata?: Record<string, any>;

  /**
   * Model runtime configuration
   * Used as fallback when call_llm instruction doesn't specify model/provider
   */
  modelRuntimeConfig?: {
    model: string;
    provider: string;
    /**
     * Compression model configuration
     * Used for context compression tasks
     */
    compressionModel?: {
      model: string;
      provider: string;
    };
  };
  operationId: string;

  /** Operation-level tool set snapshot (immutable after creation) */
  operationToolSet?: OperationToolSet;
  pendingHumanPrompt?: { metadata?: Record<string, unknown>; prompt: string };
  pendingHumanSelect?: {
    metadata?: Record<string, unknown>;
    multi?: boolean;
    options: Array<{ label: string; value: string }>;
    prompt?: string;
  };

  // --- HIL ---
  /**
   * When status is 'waiting_for_human', this stores pending requests
   * for human-in-the-loop operations.
   */
  pendingToolsCalling?: ChatToolPayload[];
  /**
   * Security blacklist configuration
   * These rules will ALWAYS block execution and require human intervention,
   * regardless of user settings (even in auto-run mode).
   * If not provided, DEFAULT_SECURITY_BLACKLIST will be used.
   */
  securityBlacklist?: SecurityBlacklistConfig;
  // --- State Machine ---
  status:
    | 'idle'
    | 'running'
    | 'waiting_for_human'
    | 'waiting_for_async_tool'
    | 'done'
    | 'error'
    | 'interrupted';

  // --- Execution Tracking ---
  /**
   * Number of execution steps in this session.
   * Incremented on each runtime.step() call.
   */
  stepCount: number;

  systemRole?: string;
  /** Tool executor map for routing tool execution between server and client */
  toolExecutorMap?: Record<string, ToolExecutor>;

  toolManifestMap: Record<string, any>;

  tools?: any[];

  /** Tool source map for routing tool execution to correct handler */
  toolSourceMap?: Record<string, ToolSource>;
  // --- Usage and Cost Tracking ---
  /**
   * Accumulated usage statistics for this session.
   * Tracks tokens, API calls, tool usage, etc.
   */
  usage: Usage;

  /**
   * User's global intervention configuration
   * Controls how tools requiring approval are handled
   */
  userInterventionConfig?: UserInterventionConfig;
}

/**
 * OpenAI Tool Call
 */
export interface ToolsCalling {
  function: {
    arguments: string;
    name: string; // A JSON string of arguments
  };
  id: string;
  /**
   * Gemini 3.x thought signature, captured from `functionCall.thoughtSignature` in the
   * streaming response. Must be round-tripped back in subsequent requests or Gemini will
   * 400 with a misleading "ordering" error. Optional; only set for Gemini 3.x tool calls.
   */
  thoughtSignature?: string;
  type: 'function';
}

/**
 * A registry for tools, mapping tool names to their implementation.
 */
export type ToolRegistry = Record<string, (args: any) => Promise<any>>;
