<?php

namespace App\Agent\Tools\Campaign;

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

/** When the campaign in focus runs. */
class SetSchedule implements Tool
{
    use ActsOnFocusedCampaign;

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

    public function description(): Stringable|string
    {
        return 'Set the start and end dates of the campaign in focus. Omit the end date to '
            .'run continuously. Dates are ISO 8601, for example 2026-10-01T09:00:00Z.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'starts_at' => $schema->string()->description('When the campaign should start.'),
            'ends_at' => $schema->string()->description('When it should stop. Omit to run continuously.'),
        ];
    }

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

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

        foreach (['starts_at', 'ends_at'] as $field) {
            if (! array_key_exists($field, $arguments)) {
                continue;
            }

            if (blank($arguments[$field])) {
                $campaign->{$field} = null;
                $changed[$field] = null;

                continue;
            }

            try {
                $campaign->{$field} = Carbon::parse((string) $arguments[$field]);
            } catch (Throwable) {
                return $this->json(['ok' => false, 'error' => "[{$arguments[$field]}] is not a date I can read."]);
            }

            $changed[$field] = $campaign->{$field}->toIso8601String();
            $this->workspace->recordSource($campaign, $field, ArtifactFieldSource::USER_STATED);
        }

        if ($changed === []) {
            return $this->json(['ok' => false, 'error' => 'Pass a start date, an end date, or both.']);
        }

        if ($campaign->starts_at && $campaign->ends_at && $campaign->ends_at->lte($campaign->starts_at)) {
            return $this->json(['ok' => false, 'error' => 'The end date must be after the start date.']);
        }

        $campaign->save();

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