<?php

namespace App\Contracts;

/**
 * AgentContract
 *
 * Interface every ChargePanda AI agent must implement.
 *
 * NOTE: This contract is intentionally independent of the Laravel AI SDK so that
 * ChargePanda core does not require `laravel/ai` to be installed. The SDK dependency
 * lives in AiAgentsCore only. AbstractAgent (in AiAgentsCore) implements this contract
 * alongside the SDK's own Agent interface.
 *
 * Agents are registered with AgentRegistry via AbstractModuleServiceProvider::registerAgent().
 */
interface AgentContract
{
    // -------------------------------------------------------------------------
    // Identity
    // -------------------------------------------------------------------------

    /**
     * Unique machine-readable slug, e.g. 'seo-keyword-research'.
     * Used as the URL segment and registry key. Must be globally unique.
     */
    public function slug(): string;

    /**
     * Human-readable display name shown in the UI, e.g. 'Keyword Research'.
     */
    public function displayName(): string;

    /**
     * One-sentence description shown on the agent picker card.
     */
    public function description(): string;

    /**
     * Category name used to group agents on the picker page, e.g. 'SEO', 'Sales'.
     */
    public function category(): string;

    /**
     * Tabler icon class for the agent card (admin views), e.g. 'ti-search'.
     */
    public function icon(): string;

    /**
     * Material Symbols icon name for account/frontend views, e.g. 'search'.
     */
    public function materialIcon(): string;

    // -------------------------------------------------------------------------
    // UI / rendering
    // -------------------------------------------------------------------------

    /**
     * Form field definitions rendered by the run-form partial.
     *
     * Each element is an associative array with keys:
     *   name        (required) — HTML name attribute
     *   type        (required) — text|textarea|url|email|select|multiselect|number|toggle|hidden
     *   label       (required) — display label
     *   placeholder (optional)
     *   help        (optional) — helper text displayed below the field
     *   required    (optional, default false)
     *   default     (optional) — pre-filled value
     *   options     (required for select/multiselect) — ['value' => 'Label']
     *   min         (optional, for number)
     *   max         (optional, for number)
     *   rows        (optional, for textarea, default 4)
     *   maxlength   (optional)
     *
     * @return array<int, array<string, mixed>>
     */
    public function inputSchema(): array;

    /**
     * Output format used by OutputFormatter.
     *
     * 'text'       — rendered as sanitised Markdown HTML
     * 'structured' — array rendered as definition lists / tables / labelled fields
     * 'html'       — rendered directly (strip_tags to allowed list)
     */
    public function outputFormat(): string;

    /**
     * Short example output shown as a preview on the agent card. Return null to omit.
     */
    public function exampleOutput(): ?string;

    // -------------------------------------------------------------------------
    // Billing / plan gating
    // -------------------------------------------------------------------------

    /**
     * PlanEntitlement key that controls access to this agent.
     * e.g. 'seo_keyword_research'. Defaults to slug() in AbstractAgent.
     */
    public function planKey(): string;

    /**
     * How many run credits this agent consumes per execution.
     * Counted against the 'agent_runs_per_month' plan entitlement.
     * Defaults to 1.
     */
    public function runsPerUnit(): int;

    // -------------------------------------------------------------------------
    // Behaviour flags
    // -------------------------------------------------------------------------

    /**
     * Whether this agent supports multi-turn conversations via RemembersConversations.
     * Defaults to false.
     */
    public function isConversational(): bool;

    /**
     * Rough execution time hint shown in the UI ("This may take ~Xs").
     * Used for the countdown timer and the polling timeout multiplier.
     */
    public function estimatedSeconds(): int;

    /**
     * Arbitrary tags for filtering/display, e.g. ['free'], ['pro'], ['agency'].
     *
     * @return string[]
     */
    public function tags(): array;
}
