<?php

namespace App\Agent\Tools\Campaign;

use App\Agent\Workspace;
use App\Models\ArtifactFieldSource;
use App\Models\Campaign;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Tool;
use Laravel\Ai\Tools\Request;
use Stringable;

/**
 * Create a campaign in this conversation.
 *
 * The worked example for the pattern every module should follow:
 *
 *   1. a plain Tool, no knowledge of the agent or the registry
 *   2. the Workspace injected, so the tool never has to be told the context
 *   3. produced() to link and focus the new artifact in one step
 *   4. recordSource() for every field, so the publish gate can tell a stated
 *      value from a guessed one later
 *
 * A campaign row is created only here, never implicitly when a chat starts.
 * A conversation is a workspace, not a campaign.
 */
class StartCampaign implements Tool
{
    public function __construct(private readonly Workspace $workspace) {}

    public function description(): Stringable|string
    {
        return 'Create a new campaign in this conversation and make it the item in focus. '
            .'Use when the user wants to build a campaign. Everything is created as a draft; '
            .'nothing reaches an advertising platform until the user approves it separately.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'name' => $schema->string()
                ->description('A short descriptive campaign name.')
                ->required(),
            'platform' => $schema->string()
                ->description('One of meta, google, tiktok, taboola, linkedin.')
                ->required(),
            'objective' => $schema->string()
                ->description('The campaign objective, if the user has stated or implied one.'),
        ];
    }

    public function handle(Request $request): Stringable|string
    {
        // Read through all(): the Request's offsetGet raises on a missing key,
        // and optional arguments are simply absent rather than null.
        $arguments = $request->all();

        $platform = strtolower(trim((string) ($arguments['platform'] ?? '')));
        $objective = $arguments['objective'] ?? null;
        $supported = array_keys((array) config('creative.platform_adapters', []));

        if (! in_array($platform, $supported, true)) {
            return $this->json([
                'ok' => false,
                'error' => "[{$platform}] is not a platform this product supports.",
                'supported' => $supported,
            ]);
        }

        $campaign = Campaign::query()->create([
            'user_id' => auth()->id(),
            'name' => trim((string) ($arguments['name'] ?? '')),
            'platform' => $platform,
            'objective' => filled($objective) ? (string) $objective : null,
            'status' => 'draft',
        ]);

        $this->workspace->produced($campaign, $request->toolCallId());

        // The user named the campaign and picked the platform; the objective is
        // the model's reading unless they said it outright, so it is marked as
        // inferred and will need confirming before anything spends.
        $this->workspace->recordSource($campaign, 'name', ArtifactFieldSource::USER_STATED);
        $this->workspace->recordSource($campaign, 'platform', ArtifactFieldSource::USER_STATED);

        if (filled($objective)) {
            $this->workspace->recordSource($campaign, 'objective', ArtifactFieldSource::MODEL_INFERRED);
        }

        return $this->json([
            'ok' => true,
            'campaign_id' => $campaign->id,
            'name' => $campaign->name,
            'platform' => $campaign->platform,
            'status' => $campaign->status,
            'now_in_focus' => true,
        ]);
    }

    private function json(array $payload): string
    {
        return json_encode($payload, JSON_UNESCAPED_SLASHES);
    }
}
