<?php

namespace Tests\Feature;

use App\Agent\Tools\Campaign\SetCampaignBudget;
use App\Agent\Tools\Campaign\SetTargeting;
use App\Agent\Workspace;
use App\Models\ArtifactFieldSource;
use App\Models\Campaign;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Ai\Tools\Request as ToolRequest;
use Tests\TestCase;

/**
 * Where the panel says a value came from.
 *
 * The green dot reads "you said this". It was written for every value these
 * tools touched, including ones the model chose on its own: a browser run
 * showed a 20.00 daily budget and US targeting marked as the user's when
 * neither had been asked. Someone approving that summary is approving a budget
 * they never set, and the publish gate only refuses outright guesses, so
 * nothing downstream catches it.
 *
 * What separates the two is whether the question was ever on screen, which the
 * workspace already records.
 */
class ProvenanceTest extends TestCase
{
    use RefreshDatabase;

    private Workspace $workspace;

    protected function setUp(): void
    {
        parent::setUp();

        config([
            'platforms.guardrails.allowed_ad_accounts' => ['act_777'],
            'platforms.guardrails.budget_ceiling_currency' => 'USD',
            'platforms.guardrails.max_daily_budget' => 100,
        ]);

        $user = User::factory()->create();
        $this->actingAs($user);

        $this->workspace = app(Workspace::class);
        $this->workspace->bindTo('conv-provenance-001');
        $this->workspace->ownedBy($user);
    }

    private function campaign(): Campaign
    {
        $campaign = Campaign::create([
            'user_id' => auth()->id(),
            'name' => 'Winter Sale',
            'platform' => 'meta',
            'status' => 'draft',
            'objective' => 'OUTCOME_TRAFFIC',
            'currency' => 'USD',
        ]);

        $this->workspace->produced($campaign);
        $this->workspace->focusOn($campaign);

        return $campaign;
    }

    private function sourceOf(Campaign $campaign, string $field): ?string
    {
        return $this->workspace->sourcesFor($campaign)[$field] ?? null;
    }

    // ------------------------------------------------------------- budget

    public function test_a_budget_the_model_chose_is_not_recorded_as_the_users(): void
    {
        $campaign = $this->campaign();

        // Nothing was offered, so nobody was asked. This is the browser case.
        app(SetCampaignBudget::class)->handle(new ToolRequest(['amount' => 20]));

        $this->assertSame(ArtifactFieldSource::MODEL_INFERRED, $this->sourceOf($campaign, 'budget'));
    }

    public function test_a_budget_answered_from_the_options_is_the_users(): void
    {
        $campaign = $this->campaign();

        $this->workspace->rememberChoices([['field' => 'budget_amount', 'options' => []]]);

        app(SetCampaignBudget::class)->handle(new ToolRequest(['amount' => 20]));

        $this->assertSame(ArtifactFieldSource::USER_STATED, $this->sourceOf($campaign, 'budget'));
    }

    public function test_a_budget_strategy_nobody_was_asked_about_is_not_the_users(): void
    {
        $campaign = $this->campaign();

        app(SetCampaignBudget::class)->handle(new ToolRequest(['amount' => 20, 'mode' => 'lifetime']));

        $this->assertSame(ArtifactFieldSource::MODEL_INFERRED, $this->sourceOf($campaign, 'budget_mode'));
    }

    // ----------------------------------------------------------- targeting

    public function test_countries_the_model_chose_are_not_recorded_as_the_users(): void
    {
        $campaign = $this->campaign();

        app(SetTargeting::class)->handle(new ToolRequest([
            'countries' => ['US'],
            'placements' => ['facebook'],
        ]));

        $this->assertSame(ArtifactFieldSource::MODEL_INFERRED, $this->sourceOf($campaign, 'locations'));
    }

    public function test_countries_answered_from_the_options_are_the_users(): void
    {
        $campaign = $this->campaign();

        $this->workspace->rememberChoices([
            ['field' => 'countries', 'options' => []],
            ['field' => 'placements', 'options' => []],
        ]);

        app(SetTargeting::class)->handle(new ToolRequest([
            'countries' => ['US'],
            'placements' => ['facebook'],
        ]));

        $this->assertSame(ArtifactFieldSource::USER_STATED, $this->sourceOf($campaign, 'locations'));
        $this->assertSame(ArtifactFieldSource::USER_STATED, $this->sourceOf($campaign, 'placements'));
    }

    /**
     * Each field is judged on its own question.
     *
     * Countries were asked and placements were not, so one is the user's and
     * the other is not. Recording them together is how a single answered
     * question came to vouch for everything the tool wrote.
     */
    public function test_fields_are_judged_by_their_own_question(): void
    {
        $campaign = $this->campaign();

        $this->workspace->rememberChoices([['field' => 'countries', 'options' => []]]);

        app(SetTargeting::class)->handle(new ToolRequest([
            'countries' => ['US'],
            'placements' => ['facebook'],
        ]));

        $this->assertSame(ArtifactFieldSource::USER_STATED, $this->sourceOf($campaign, 'locations'));
        $this->assertSame(ArtifactFieldSource::MODEL_INFERRED, $this->sourceOf($campaign, 'placements'));
    }
}
