<?php

namespace Tests\Feature;

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

/**
 * Brevity is for turns that are going well.
 *
 * A flat 90 word cap is right for the ordinary case, where the reply is one
 * line beside a set of buttons and anything longer is the model narrating
 * itself. It is wrong for the case it also governed: a publish refused by the
 * gate, a platform rejecting a budget, a creative Meta will not approve.
 *
 * Those are the turns where the buyer has to do something and cannot see why,
 * and they are the turns where a cap makes the answer shorter instead of
 * clearer. Raising it everywhere would have made every routine turn verbose,
 * which is what the cap exists to prevent, so the exception is scoped to
 * failures rather than the number being changed.
 */
class ReplyLengthAllowsExplainingFailuresTest extends TestCase
{
    use RefreshDatabase;

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

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

    /** The ordinary cap is still there, because most turns are ordinary. */
    public function test_the_ninety_word_limit_still_applies_to_a_normal_turn(): void
    {
        $this->assertStringContainsString(
            'Keep replies under 90 words',
            app(Instructions::class)->build(),
        );
    }

    /**
     * Asserted within single lines: the prompt is a heredoc and wraps, so
     * matching across a break tests the indentation rather than the rule.
     */
    public function test_a_failure_may_take_the_words_it_needs(): void
    {
        $text = app(Instructions::class)->build();

        $this->assertStringContainsString('That limit is for turns that are going well', $text);
        $this->assertStringContainsString('take the words it needs', $text);
    }

    /** And it says what those words are for, not merely that more are allowed. */
    public function test_it_says_what_a_failure_reply_has_to_cover(): void
    {
        $text = app(Instructions::class)->build();

        $this->assertStringContainsString('say what happened, why, and what', $text);
        $this->assertStringContainsString('leaves the user unable to act is not concise', $text);
    }

    /**
     * The exception is scoped, not a licence to be long everywhere.
     *
     * If this stops naming the failing case then the cap has effectively been
     * lifted for every turn, which is a different change from the one asked for.
     */
    public function test_the_exception_is_scoped_to_failures(): void
    {
        $this->assertStringContainsString(
            'refused, failed or',
            app(Instructions::class)->build(),
        );
    }
}
