<?php

namespace App\Agent\Tools\Campaign;

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

/**
 * What has changed since the campaign went live.
 *
 * Read only. Its job is to stop the agent claiming a change took effect when it
 * only reached our copy of the campaign, which is what happened before anything
 * tracked the difference.
 */
class ReviewChanges implements Tool
{
    use ActsOnFocusedCampaign;

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

    public function description(): Stringable|string
    {
        return 'Show what has changed on the campaign in focus since it was published, and '
            .'whether those changes can be pushed to the platform. Call this after editing a '
            .'live campaign, before telling the user anything took effect.';
    }

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

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

        if (! $campaign->isPublished()) {
            return $this->json([
                'ok' => true,
                'published' => false,
                'note' => 'This campaign is not live yet, so edits apply directly. Nothing to sync.',
            ]);
        }

        $updatable = $this->pending->updatable($campaign);
        $rebuild = $this->pending->requiringRebuild($campaign);

        return $this->json(array_filter([
            'ok' => true,
            'published' => true,
            'pending_changes' => $updatable ?: null,
            'cannot_be_updated' => $rebuild ?: null,
            'note' => match (true) {
                $updatable === [] && $rebuild === [] => 'The live campaign matches what we hold. Nothing to push.',
                $rebuild !== [] => 'Some changes cannot be applied to a live campaign. Tell the user plainly '
                    .'rather than implying they took effect.',
                default => 'Call push_changes to send these to the platform. The user must approve first.',
            },
        ], fn ($v) => $v !== null));
    }
}
