<?php

namespace App\Agent\Tools\Campaign;

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

/** Set the objective and landing page on the campaign in focus. */
class SetCampaignBasics implements Tool
{
    use ActsOnFocusedCampaign;

    public function __construct(private readonly Workspace $workspace) {}

    public function description(): Stringable|string
    {
        return 'Set the objective and/or landing page URL on the campaign in focus. '
            .'Objective must be one of OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'objective' => $schema->string()
                ->description('OUTCOME_SALES, OUTCOME_LEADS or OUTCOME_TRAFFIC.'),
            'landing_url' => $schema->string()
                ->description('The page the ad sends people to. Must be a full URL.'),
            'name' => $schema->string()->description('Rename the campaign.'),
        ];
    }

    public function handle(Request $request): Stringable|string
    {
        if (! $campaign = $this->focused()) {
            return $this->noCampaign();
        }

        $arguments = $request->all();
        $changed = [];

        if (filled($arguments['objective'] ?? null)) {
            $objective = strtoupper((string) $arguments['objective']);

            $rules = app(Platforms::class)->for($campaign);

            if (! in_array($objective, $rules->objectives(), true)) {
                return $this->json([
                    'ok' => false,
                    'error' => "[{$objective}] is not supported on {$rules->name()}.",
                    'supported' => $rules->objectives(),
                ]);
            }

            $campaign->objective = $objective;
            $campaign->optimization_goal = $rules->optimizationGoal($objective);
            $this->workspace->recordSource($campaign, 'objective', ArtifactFieldSource::USER_STATED);
            $changed['objective'] = $objective;
            $changed['optimization_goal'] = $campaign->optimization_goal;
        }

        if (filled($arguments['landing_url'] ?? null)) {
            $url = trim((string) $arguments['landing_url']);

            if (! filter_var($url, FILTER_VALIDATE_URL)) {
                return $this->json(['ok' => false, 'error' => "[{$url}] is not a valid URL."]);
            }

            $campaign->landing_url = $url;
            $this->workspace->recordSource($campaign, 'landing_url', ArtifactFieldSource::USER_STATED);
            $changed['landing_url'] = $url;
        }

        if (filled($arguments['name'] ?? null)) {
            $campaign->name = trim((string) $arguments['name']);
            $this->workspace->recordSource($campaign, 'name', ArtifactFieldSource::USER_STATED);
            $changed['name'] = $campaign->name;
        }

        if ($changed === []) {
            return $this->json(['ok' => false, 'error' => 'Nothing to set. Pass at least one field.']);
        }

        $campaign->save();

        return $this->json(['ok' => true, 'campaign_id' => $campaign->id, ...$changed]);
    }
}
