// src/Tool.d.ts

export type ToolActionCallback = (params: Record<string, any> & { raw?: string }, ...args: any[]) => Promise<any>;

/**
 * Options for defining a tool parameter.
 */
export interface ToolParamOptions {
    /** The data type of the parameter (e.g., "string", "number", "boolean", "object", "array"). Defaults to "string". */
    type?: string;
    /** Whether the parameter is required. Defaults to true. */
    required?: boolean;
    /** An optional array of allowed values for the parameter. */
    enum?: Array<string | number | boolean>;
}

/**
 * Internal structure holding parameter details.
 */
interface ToolParamDetails extends Required<ToolParamOptions> {
    description: string;
    enum?: Array<string | number | boolean>; // Optional enum remains optional
}

/**
 * Represents a single invokable function (tool) that the LLM can use.
 * Uses a fluent API for definition.
 */
export declare class Tool {
    /**
     * The unique name of the tool. Should contain only letters, numbers, and underscores.
     * @readonly
     */
    readonly name: string;

    #description: string;
    #params: Record<string, ToolParamDetails>;
    #rawDescription: string | null;
    #action: ToolActionCallback;

    /**
     * Creates a new Tool instance.
     * @param name The name of the tool. Must be a non-empty string containing only letters, numbers, and underscores.
     * @throws {Error} If the name is invalid.
     */
    constructor(name: string);

    /**
     * Static factory method to create a new Tool instance.
     * @param name The name of the tool.
     * @returns A new Tool instance.
     */
    static make(name: string): Tool;

    /**
     * Sets the description for the tool.
     * @param description A human-readable explanation of the tool's purpose.
     * @returns The Tool instance for chaining.
     * @throws {Error} If the description is not a string.
     */
    description(description: string): this;

    /**
     * Alias for `description()`.
     * @param description A human-readable explanation of the tool's purpose.
     * @returns The Tool instance for chaining.
     */
    desc(description: string): this;

    /**
     * Defines a parameter accepted by the tool.
     * @param name The name of the parameter. Must be a non-empty string.
     * @param description A description of the parameter's purpose.
     * @param options Options object or a string representing the type (defaults to "string").
     *        If a string is provided, it's treated as the `type`.
     *        If an object, it can contain `type` (default "string"), `required` (default true), and `enum` (array).
     * @returns The Tool instance for chaining.
     * @throws {Error} If name or description are invalid, or if enum is not an array.
     */
    param(name: string, description: string, options?: ToolParamOptions | string): this;

    /**
     * Specifies that the tool accepts raw text input between the function call tags.
     * @param description A description explaining the purpose of the raw input. Defaults to "Raw text input for the tool.".
     * @returns The Tool instance for chaining.
     * @throws {Error} If the description is not a string.
     */
    raw(description?: string): this;

    /**
     * Sets the function to be executed when the tool is called.
     * @param callback The async function to execute.
     *        It receives parsed parameters (including `raw` if applicable) and additional arguments.
     * @returns The Tool instance for chaining.
     * @throws {Error} If the callback is not a function.
     */
    action(callback: ToolActionCallback): this;

    /**
     * Builds the string representation of the tool's definition for the LLM prompt.
     * @returns A formatted string describing the tool, its parameters, and raw input requirement.
     * @internal This method is primarily for internal use by the Conversation class.
     */
    buildPromptString(): string;

    /**
     * Executes the tool's action with the provided parameters and raw input.
     * Validates required parameters before execution.
     * @param params Parameter values provided for the call.
     * @param raw Raw text input provided for the call (if the tool defines it). Should be null/undefined if not applicable/provided.
     * @param args Additional arguments to pass to the action function.
     * @returns A promise that resolves with the result of the tool's action, or an object containing an `error` property if execution fails.
     * @throws {Error} If a required parameter is missing (this indicates a logic error before calling, as Conversation should parse correctly).
     * @internal This method is primarily for internal use by the Conversation class.
     */
    call(params: Record<string, any>, raw: string | null | undefined, args?: any[]): Promise<any>;
}