<?php

namespace App\Providers;

use App\Agent\Instructions;
use App\Agent\ToolRegistry;
use App\Agent\Tools\Campaign\ChoosePage;
use App\Agent\Tools\Campaign\ChoosePixel;
use App\Agent\Tools\Campaign\ListAdAccounts;
use App\Agent\Tools\Campaign\RequestPublish;
use App\Agent\Tools\Campaign\ReviewAssets;
use App\Agent\Tools\Campaign\SetBidding;
use App\Agent\Tools\Campaign\SetCampaignBasics;
use App\Agent\Tools\Campaign\SetCampaignBudget;
use App\Agent\Tools\Campaign\SetTargeting;
use App\Agent\Tools\Campaign\StartCampaign;
use App\Agent\Tools\Campaign\VerifyAdAccount;
use App\Agent\Tools\Campaign\WriteAdCopy;
use App\Agent\Tools\SwitchFocus;
use App\Agent\Workspace;
use Illuminate\Support\ServiceProvider;

/**
 * Wires the agent core.
 *
 * The registry is a singleton so any provider can add to it. Other modules
 * should register their own tools from their own provider rather than adding
 * them here:
 *
 *     public function boot(ToolRegistry $registry): void
 *     {
 *         $registry->register('creative', GenerateImage::class, ApproveCreative::class);
 *     }
 *
 * That keeps campaign, creative, landing page and analysis work independent.
 */
class AgentServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // Scoped, not singleton: one workspace per request, so a queued job
        // handling a different conversation never inherits another's focus.
        $this->app->scoped(Workspace::class, fn (): Workspace => new Workspace);

        $this->app->singleton(ToolRegistry::class);

        $this->app->bind(Instructions::class, fn ($app): Instructions => new Instructions(
            $app->make(Workspace::class),
        ));
    }

    public function boot(ToolRegistry $registry): void
    {
        // Focus is core rather than campaign-specific: every module's artifacts
        // can be switched to.
        $registry->register('workspace', SwitchFocus::class);

        // Listed in the order a campaign is usually assembled: the model reads
        // the declarations top to bottom and that ordering nudges the sequence.
        $registry->register(
            'campaign',
            StartCampaign::class,
            SetCampaignBasics::class,
            SetCampaignBudget::class,
            SetTargeting::class,
            SetBidding::class,
            WriteAdCopy::class,
            ListAdAccounts::class,
            VerifyAdAccount::class,
            ChoosePage::class,
            ChoosePixel::class,
            ReviewAssets::class,
            RequestPublish::class,
        );
    }
}
