<?php

namespace App\Agent\Tools\Campaign;

use App\Agent\Choices;
use App\Agent\Tools\Campaign\Concerns\ActsOnFocusedCampaign;
use App\Agent\Workspace;
use App\Campaigns\PublishGate;
use App\Campaigns\TrackedUrl;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Tool;
use Laravel\Ai\Tools\Request;
use Stringable;

/**
 * Ask for the campaign in focus to be published.
 *
 * This is a request, not an act. It records what would be created and returns
 * the summary for the user to approve; nothing reaches a platform until a human
 * approves separately. The agent has no tool that publishes.
 */
class RequestPublish implements Tool
{
    use ActsOnFocusedCampaign;

    public function __construct(
        private readonly Workspace $workspace,
        private readonly PublishGate $gate,
        private readonly Choices $choices,
    ) {}

    public function description(): Stringable|string
    {
        return 'Check whether the campaign in focus is ready and ask the user to approve it. '
            .'Call this when nothing is blocking. You cannot publish; only the user can.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [];
    }

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

        if ($blocking = $this->gate->check($campaign)) {
            return $this->json([
                'ok' => false,
                'ready' => false,
                'still_needed' => $blocking,
            ]);
        }

        $options = [
            [
                'value' => 'approve',
                'label' => 'Approve & Publish',
                'hint' => 'Create on '.ucfirst($campaign->platform).' in paused state',
                'sends' => 'Approve and publish the campaign.',
            ],
            [
                'value' => 'edit',
                'label' => 'Make Changes',
                'hint' => 'Adjust budget, targeting, bidding, or ad copy',
                'sends' => 'I want to make changes to the campaign first.',
            ],
            [
                'value' => 'reject',
                'label' => 'Cancel / Reject',
                'hint' => 'Keep as draft without publishing',
                'sends' => 'Do not publish this campaign.',
            ],
        ];

        $this->choices->offer(
            field: 'publish_approval',
            question: 'Approve publishing? It will be created paused.',
            options: $options,
            multiple: false,
            allowOther: false,
        );

        return $this->json([
            'ok' => true,
            'ready' => true,
            'summary' => [
                'campaign' => $campaign->name,
                'objective' => $campaign->objective,
                'landing_url' => $campaign->landing_url,
                // Where a click actually lands, with Meta's macros filled in,
                // since that is the thing being approved.
                'destination_url' => TrackedUrl::asExample($campaign),
                // Named for what it is. A summary reading "daily budget" over a
                // lifetime one, or over a budget Meta will split across ad sets,
                // is the kind of thing somebody approves without noticing.
                'budget' => $campaign->budget,
                'budget_is' => sprintf(
                    '%s, held on the %s',
                    $campaign->usesLifetimeBudget() ? 'a total for the whole run' : 'per day',
                    $campaign->usesCampaignBudget() ? 'campaign and split across ad sets by Meta' : 'ad set',
                ),
                'currency' => $campaign->currency,
                'bidding' => $campaign->bid_strategy,
                'target_cost' => $campaign->bid_amount,
                'countries' => $campaign->locations['countries'] ?? [],
                'placements' => $campaign->placements,
                'ad_account_id' => $campaign->ad_account_id,
                'page_id' => $campaign->page_id,
                'pixel_id' => $campaign->pixel_id,
                'ads' => $campaign->ads()->count(),
            ],
            'note' => 'Show the user this summary, including the ad account, Page and pixel ids, '
                .'and ask "Approve publishing? It will be created paused." Options are on screen; say one short line and wait.',
        ]);
    }
}
