<?php

namespace Tests\Feature;

use App\Agent\MarketingAgent;
use App\Models\Campaign;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

/**
 * Saying where the ads go is an answer, not a topic.
 *
 * The controller steps in when the model offers nothing, and it called
 * start_campaign with no arguments, which always puts the platform chooser on
 * screen. So a message that already said where the ads should run was met with
 * "Where should this run?".
 *
 * Seen on arb-dev on 25 Sep: "Advertise https://iblockads.org/ on Meta and
 * Google, 20 a day total, split it evenly between them" produced the chooser
 * and nothing else, and the buyer had to click the two platforms they had just
 * typed.
 *
 * Asking is still right when they raised platforms without naming any, which is
 * the case the step-in was written for.
 */
class NamedPlatformsAreNotAskedAboutTest extends TestCase
{
    use RefreshDatabase;

    protected User $user;

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

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

        // The model says something unrelated, so the controller has to step in.
        MarketingAgent::fake(['Right.']);
    }

    private function send(string $message): array
    {
        return $this->postJson(route('chat.send'), ['message' => $message])
            ->assertOk()
            ->json();
    }

    /** The defect: two platforms named, and it asked which platforms. */
    public function test_two_named_platforms_are_created_rather_than_asked_about(): void
    {
        $this->send('Advertise https://iblockads.org/ on Meta and Google, 20 a day total');

        $this->assertSame(
            ['google', 'meta'],
            Campaign::query()->orderBy('platform')->pluck('platform')->all(),
        );
    }

    /** And the chooser is not put on screen, because it has been answered. */
    public function test_the_platform_chooser_is_not_offered_when_platforms_were_named(): void
    {
        $body = $this->send('Advertise https://iblockads.org/ on Meta and Google');

        $fields = array_column($body['choices'] ?? [], 'field');

        $this->assertNotContains('platforms', $fields, 'It asked a question the message had answered.');
    }

    /** One named platform is still a named platform. */
    public function test_a_single_named_platform_is_created(): void
    {
        $this->send('Run this on facebook');

        $this->assertSame('meta', Campaign::sole()->platform);
    }

    /** Raising platforms without naming any is still a question. */
    public function test_the_chooser_still_appears_when_no_platform_is_named(): void
    {
        $body = $this->send('Which platforms can I use?');

        $this->assertContains('platforms', array_column($body['choices'] ?? [], 'field'));
        $this->assertSame(0, Campaign::query()->count(), 'Nothing should be created from a question.');
    }

    /** A message about neither creates nothing and asks nothing. */
    public function test_an_unrelated_message_creates_no_campaign(): void
    {
        $this->send('What can you do?');

        $this->assertSame(0, Campaign::query()->count());
    }
}
