<?php

namespace App\Agent\Tools\Campaign;

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

/**
 * List conversion pixels, or attach one to the campaign in focus.
 *
 * The list merges the account's own pixels with those owned by its parent
 * business, because the one an advertiser means is frequently business owned
 * and shared rather than assigned to the account.
 */
class ChoosePixel implements Tool
{
    use ActsOnFocusedCampaign;

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

    public function description(): Stringable|string
    {
        return 'List available conversion pixels, or set one on the campaign in focus by passing '
            .'pixel_id. Sales and leads objectives need a pixel; traffic does not.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'pixel_id' => $schema->string()
                ->description('Set this pixel on the campaign. Omit to list the available pixels instead.'),
        ];
    }

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

        if (blank($campaign->ad_account_id)) {
            return $this->json(['ok' => false, 'error' => 'Verify the ad account first; pixels are account scoped.']);
        }

        $pixelId = $request->all()['pixel_id'] ?? null;

        try {
            $pixels = $this->meta->on($campaign->id, 'agent')->pixels($campaign->ad_account_id);
        } catch (MetaException $e) {
            return $this->json(['ok' => false, 'error' => $e->getMessage()]);
        }

        if (blank($pixelId)) {
            return $this->json(['ok' => true, 'pixels' => $pixels]);
        }

        $chosen = collect($pixels)->firstWhere('id', (string) $pixelId);

        if (! $chosen) {
            return $this->json([
                'ok' => false,
                'error' => "Pixel {$pixelId} is not available on this account or its business.",
                'pixels' => $pixels,
            ]);
        }

        $campaign->update(['pixel_id' => $chosen['id']]);
        $this->workspace->recordSource($campaign, 'pixel_id', ArtifactFieldSource::PLATFORM_RETURNED);

        return $this->json(['ok' => true, 'pixel_id' => $chosen['id'], 'name' => $chosen['name'] ?? null]);
    }
}
