<?php

declare(strict_types=1);

use App\Models\Artwork;
use App\Models\Group;
use App\Models\User;
use App\Models\UserRecommendationCache;
use App\Services\HomepageService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;

uses(RefreshDatabase::class);

beforeEach(function () {
    config(['scout.driver' => 'null']);
});

it('allForUser includes a for_you key', function () {
    $user = User::factory()->create();

    Cache::flush();

    $service = app(HomepageService::class);
    $result  = $service->allForUser($user);

    expect($result)->toHaveKey('for_you')
        ->and($result['for_you'])->toBeArray();
});

it('allForUser for_you is an array even with no cached recommendations', function () {
    $user    = User::factory()->create();
    $service = app(HomepageService::class);

    Cache::flush();

    $result = $service->allForUser($user);

    expect($result['for_you'])->toBeArray();
});

it('allForUser for_you returns items when cache exists', function () {
    $user    = User::factory()->create();
    $artwork = Artwork::factory()->create([
        'is_public'    => true,
        'is_approved'  => true,
        'published_at' => now()->subHour(),
    ]);

    UserRecommendationCache::query()->create([
        'user_id'              => $user->id,
        'algo_version'         => (string) config('discovery.algo_version', 'clip-cosine-v1'),
        'cache_version'        => (string) config('discovery.cache_version', 'cache-v1'),
        'recommendations_json' => [
            'items' => [
                ['artwork_id' => $artwork->id, 'score' => 0.9, 'source' => 'profile'],
            ],
        ],
        'generated_at' => now(),
        'expires_at'   => now()->addMinutes(60),
    ]);

    Cache::flush();

    $service = app(HomepageService::class);
    $result  = $service->allForUser($user);

    expect($result['for_you'])->toBeArray();
    // At least one item should have the base shape (id, title, slug, url)
    if (count($result['for_you']) > 0) {
        expect($result['for_you'][0])->toHaveKeys(['id', 'title', 'slug', 'url']);
    }
});

it('allForUser for_you uses group publisher payload for group-published artworks', function () {
    $user = User::factory()->create();
    $owner = User::factory()->create();
    $group = Group::factory()->create([
        'owner_user_id' => $owner->id,
        'name' => 'Nova Group',
        'slug' => 'nova-group',
    ]);

    $artwork = Artwork::factory()->create([
        'user_id' => $owner->id,
        'group_id' => $group->id,
        'published_as_type' => Artwork::PUBLISHED_AS_GROUP,
        'title' => 'Group Recommended Artwork',
        'hash' => 'grouprecommendedartwork',
        'thumb_ext' => 'webp',
        'is_public' => true,
        'is_approved' => true,
        'published_at' => now()->subHour(),
    ]);

    UserRecommendationCache::query()->create([
        'user_id' => $user->id,
        'algo_version' => (string) config('discovery.algo_version', 'clip-cosine-v1'),
        'cache_version' => (string) config('discovery.cache_version', 'cache-v1'),
        'recommendations_json' => [
            'items' => [
                ['artwork_id' => $artwork->id, 'score' => 0.91, 'source' => 'profile'],
            ],
        ],
        'generated_at' => now(),
        'expires_at' => now()->addMinutes(60),
    ]);

    Cache::flush();

    $result = app(HomepageService::class)->allForUser($user);

    expect($result['for_you'])->not->toBeEmpty()
        ->and($result['for_you'][0]['author'])->toBe('Nova Group')
        ->and($result['for_you'][0]['published_as_type'])->toBe(Artwork::PUBLISHED_AS_GROUP)
        ->and($result['for_you'][0]['publisher']['type'])->toBe('group')
        ->and($result['for_you'][0]['publisher']['name'])->toBe('Nova Group');
});
