<?php

namespace Tests\Unit;

use App\DTOs\CreativeBrief;
use App\Exceptions\VideoDialogueException;
use App\Services\AI\LaravelAiScriptGenerator;
use App\Support\VideoDialogue;
use Laravel\Ai\StructuredAnonymousAgent;
use Tests\TestCase;

class LaravelAiScriptGeneratorTest extends TestCase
{
    public function test_it_rejects_an_ai_spoken_line_that_exceeds_the_duration_budget(): void
    {
        config(['creative.spoken_words_per_second' => 1.7]);

        $overlongScript = $this->scriptWithSpokenLine(implode(' ', array_fill(0, 12, 'word')));
        StructuredAnonymousAgent::fake([$overlongScript, $overlongScript]);

        $brief = $this->brief();

        $this->expectException(VideoDialogueException::class);
        $this->expectExceptionMessage('too long');

        (new LaravelAiScriptGenerator)->generate($brief, durationSeconds: 8);
    }

    public function test_it_retries_an_overlong_line_and_keeps_a_valid_rewrite(): void
    {
        config(['creative.spoken_words_per_second' => 1.7]);
        StructuredAnonymousAgent::fake([
            $this->scriptWithSpokenLine(implode(' ', array_fill(0, 12, 'word'))),
            $this->scriptWithSpokenLine('Browse faster. Download today.'),
        ]);

        $script = (new LaravelAiScriptGenerator)->generate($this->brief(), durationSeconds: 8);

        $this->assertSame('Browse faster. Download today.', $script['spoken_line']);
        StructuredAnonymousAgent::assertPrompted(fn ($prompt): bool => str_contains($prompt->prompt, 'previous spoken_line contained 12 words'));
    }

    public function test_one_invalid_variation_does_not_discard_other_valid_scripts(): void
    {
        config(['creative.spoken_words_per_second' => 1.7]);
        $overlongScript = $this->scriptWithSpokenLine(implode(' ', array_fill(0, 12, 'word')));
        StructuredAnonymousAgent::fake([
            $overlongScript,
            $overlongScript,
            $this->scriptWithSpokenLine('Browse faster. Download today.'),
            $this->scriptWithSpokenLine('Less clutter. Try it free.'),
            $this->scriptWithSpokenLine('Faster pages. Get started.'),
        ]);

        $variations = (new LaravelAiScriptGenerator)->generateVariations($this->brief(), 4, durationSeconds: 8);

        $this->assertCount(3, $variations);
        $this->assertSame('Browse faster. Download today.', $variations[0]['spoken_line']);
    }

    public function test_vertex_dialogue_budget_matches_each_rendered_stage(): void
    {
        config(['creative.spoken_words_per_second' => 2, 'creative.vertex_extend_durations' => [15 => 1, 30 => 3]]);

        $this->assertSame(26, VideoDialogue::wordBudget(15));
        $this->assertSame(50, VideoDialogue::wordBudget(30));
    }

    private function brief(): CreativeBrief
    {
        return new CreativeBrief(
            productName: 'Example Browser',
            benefits: ['Faster pages'],
            features: ['Built-in ad blocker'],
            images: [],
            messaging: 'Simple browser ad',
            cta: 'Download today',
        );
    }

    private function scriptWithSpokenLine(string $spokenLine): array
    {
        return [
            'hook' => 'Discover faster browsing',
            'spoken_line' => $spokenLine,
            'visual_action' => 'Presenter addresses the camera.',
            'problem' => 'Slow pages',
            'product' => 'Example Browser',
            'benefits' => 'Faster pages',
            'cta' => 'Download today',
        ];
    }
}
