<?php

namespace Tests\Feature;

use App\Contracts\CreativeBriefResolver;
use App\Contracts\CreativeTitleGenerator;
use App\Contracts\ImageCreativeGenerator;
use App\Jobs\GenerateImageCreativeJob;
use App\Models\Creative;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Storage;
use Laravel\Ai\Image;
use Laravel\Ai\StructuredAnonymousAgent;
use Tests\TestCase;

class GenerateImageCreativeJobTest extends TestCase
{
    use RefreshDatabase;

    public function test_scheduled_worker_targets_the_configured_database_queue(): void
    {
        Artisan::call('schedule:list');

        $queue = config('queue.connections.database.queue');
        $this->assertStringContainsString("--queue={$queue}", Artisan::output());
    }

    public function test_it_generates_an_image_creative_from_a_prompt(): void
    {
        $this->travelTo(Carbon::parse('2026-09-30 12:00:00'));
        Storage::fake('public');

        StructuredAnonymousAgent::fake([
            [
                'product_name' => 'Chromium Browser',
                'benefits' => ['Faster browsing', 'No annoying ads'],
                'features' => ['Built-in ad blocker'],
                'images' => [],
                'messaging' => 'Clean and premium',
                'cta' => 'Get Chromium Browser Free',
            ],
            ['title' => 'Ad-free Browsing'],
        ]);

        Image::fake();

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

        $creative = Creative::create([
            'user_id' => $user->id,
            'type' => 'image',
            'status' => 'queued',
            'source' => 'prompt',
            'prompt' => 'Create a modern ad for Chromium Browser.',
            'ratio' => '1:1',
        ]);

        $this->travel(1)->days();

        (new GenerateImageCreativeJob($creative->id))->handle(
            app(CreativeBriefResolver::class),
            app(ImageCreativeGenerator::class),
            app(CreativeTitleGenerator::class),
        );

        $creative->refresh();

        $this->assertSame('completed', $creative->status);
        $this->assertSame('ad-free-browsing_Image-1200x1200_2026-09-30', $creative->title);
        $this->assertSame('openai', $creative->provider['provider']);
        $this->assertNotNull($creative->asset_path);
        $this->assertNull($creative->failure_reason);
        Storage::disk('public')->assertExists($creative->asset_path);
    }

    public function test_it_marks_a_stopped_worker_job_as_failed(): void
    {
        $creative = Creative::create([
            'user_id' => User::factory()->create()->id,
            'type' => 'image',
            'status' => 'processing',
            'source' => 'prompt',
            'prompt' => 'Create an ad.',
            'ratio' => '1:1',
        ]);

        (new GenerateImageCreativeJob($creative->id))->failed(new \RuntimeException('Worker timed out at a vendor endpoint'));

        $this->assertSame('failed', $creative->fresh()->status);
        $this->assertSame('Generation failed. Please try again.', $creative->fresh()->failure_reason);
    }

    public function test_it_marks_the_creative_as_failed_when_generation_throws(): void
    {
        StructuredAnonymousAgent::fake([
            [
                'product_name' => 'Chromium Browser',
                'benefits' => [],
                'features' => [],
                'images' => [],
                'messaging' => '',
                'cta' => '',
            ],
        ]);

        Image::fake(fn () => throw new \RuntimeException('Provider unavailable'));

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

        $creative = Creative::create([
            'user_id' => $user->id,
            'type' => 'image',
            'status' => 'queued',
            'source' => 'prompt',
            'prompt' => 'Create an ad.',
            'ratio' => '1:1',
        ]);

        try {
            (new GenerateImageCreativeJob($creative->id))->handle(
                app(CreativeBriefResolver::class),
                app(ImageCreativeGenerator::class),
                app(CreativeTitleGenerator::class),
            );
            $this->fail('Expected exception was not thrown.');
        } catch (\RuntimeException $e) {
            $this->assertSame('Provider unavailable', $e->getMessage());
        }

        $creative->refresh();

        $this->assertSame('failed', $creative->status);
        $this->assertSame('Generation failed. Please try again.', $creative->failure_reason);
    }
}
