<?php

declare(strict_types=1);

use App\Jobs\AutoTagArtworkJob;
use App\Models\Artwork;
use App\Models\Category;
use App\Models\ContentType;
use App\Models\Tag;
use Illuminate\Support\Facades\Http;

it('calls CLIP analyze and attaches AI tags', function () {
    config()->set('vision.enabled', true);
    config()->set('vision.clip.base_url', 'https://clip.local');
    config()->set('vision.clip.endpoint', '/analyze');
    config()->set('vision.yolo.enabled', false);
    config()->set('cdn.files_url', 'https://files.local');

    Http::fake([
        'https://clip.local/analyze' => Http::response([
            ['tag' => 'Cyber Punk', 'confidence' => 0.42],
            ['tag' => 'City', 'confidence' => 0.31],
        ], 200),
    ]);

    $artwork = Artwork::factory()->create();
    $hash = 'abcdef123456';

    (new AutoTagArtworkJob($artwork->id, $hash))->handle(app(\App\Services\TagService::class), app(\App\Services\TagNormalizer::class));

    expect(Tag::query()->whereIn('slug', ['cyber-punk', 'city'])->count())->toBe(2);
    expect($artwork->tags()->pluck('slug')->all())->toContain('cyber-punk', 'city');
});

it('optionally calls YOLO for photography', function () {
    config()->set('vision.enabled', true);
    config()->set('vision.clip.base_url', 'https://clip.local');
    config()->set('vision.clip.endpoint', '/analyze');
    config()->set('vision.yolo.base_url', 'https://yolo.local');
    config()->set('vision.yolo.endpoint', '/analyze');
    config()->set('vision.yolo.enabled', true);
    config()->set('vision.yolo.photography_only', true);
    config()->set('cdn.files_url', 'https://files.local');

    Http::fake([
        'https://clip.local/analyze' => Http::response([['tag' => 'tree', 'confidence' => 0.2]], 200),
        'https://yolo.local/analyze' => Http::response(['objects' => [['label' => 'person', 'confidence' => 0.9]]], 200),
    ]);

    $photoType = ContentType::query()->create(['name' => 'Photography', 'slug' => 'photography', 'description' => '']);
    $cat = Category::query()->create(['content_type_id' => $photoType->id, 'parent_id' => null, 'name' => 'Test', 'slug' => 'test', 'description' => '', 'image' => null, 'is_active' => true, 'sort_order' => 0]);

    $artwork = Artwork::factory()->create();
    $artwork->categories()->attach($cat->id);

    $hash = 'abcdef123456';
    (new AutoTagArtworkJob($artwork->id, $hash))->handle(app(\App\Services\TagService::class), app(\App\Services\TagNormalizer::class));

    expect($artwork->tags()->pluck('slug')->all())->toContain('tree', 'person');
});

it('does not throw on CLIP 4xx and never blocks publish', function () {
    config()->set('vision.enabled', true);
    config()->set('vision.clip.base_url', 'https://clip.local');
    config()->set('vision.clip.endpoint', '/analyze');
    config()->set('vision.yolo.enabled', false);
    config()->set('cdn.files_url', 'https://files.local');

    Http::fake([
        'https://clip.local/analyze' => Http::response(['message' => 'bad'], 422),
    ]);

    $artwork = Artwork::factory()->create();
    $hash = 'abcdef123456';

    (new AutoTagArtworkJob($artwork->id, $hash))->handle(app(\App\Services\TagService::class), app(\App\Services\TagNormalizer::class));

    expect($artwork->tags()->count())->toBe(0);
});

it('persists clip tags blip caption and yolo objects from the unified gateway response', function () {
    config()->set('vision.enabled', true);
    config()->set('vision.gateway.base_url', 'https://vision.local');
    config()->set('vision.yolo.enabled', false);
    config()->set('cdn.files_url', 'https://files.local');

    Http::fake([
        'https://vision.local/analyze/all' => Http::response([
            'clip' => [
                ['tag' => 'Neon City', 'confidence' => 0.71],
            ],
            'blip' => ['A neon city street at night'],
            'yolo' => [
                ['label' => 'car', 'confidence' => 0.88],
                ['label' => 'person', 'confidence' => 0.67],
            ],
        ], 200),
    ]);

    $artwork = Artwork::factory()->create();

    (new AutoTagArtworkJob($artwork->id, 'abcdef123456'))->handle(app(\App\Services\TagService::class), app(\App\Services\TagNormalizer::class));

    $artwork->refresh();

    expect($artwork->clip_tags_json)->toBeArray()
        ->and($artwork->clip_tags_json[0]['tag'] ?? null)->toBe('Neon City')
        ->and($artwork->blip_caption)->toBe('A neon city street at night')
        ->and($artwork->yolo_objects_json)->toBeArray()
        ->and($artwork->yolo_objects_json[0]['tag'] ?? null)->toBe('car')
        ->and($artwork->vision_metadata_updated_at)->not->toBeNull();
});
