<?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 the Pages an ad can be posted by, or attach one to the campaign in focus. */
class ChoosePage implements Tool
{
    use ActsOnFocusedCampaign;

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

    public function description(): Stringable|string
    {
        return 'List available Pages, or set one on the campaign in focus by passing page_id. '
            .'Requires the ad account to be verified first. Never invent a Page id.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'page_id' => $schema->string()
                ->description('Set this Page on the campaign. Omit to list the available Pages 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; Pages are account scoped.']);
        }

        $pageId = $request->all()['page_id'] ?? null;

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

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

        $chosen = collect($pages)->firstWhere('id', (string) $pageId);

        if (! $chosen) {
            return $this->json([
                'ok' => false,
                'error' => "Page {$pageId} is not one this token can post as.",
                'pages' => $pages,
            ]);
        }

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

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