<?php

declare(strict_types=1);

use App\Models\User;
use App\Models\Artwork;
use App\Models\Group;
use App\Services\ArtworkService;
use App\Services\HomepageService;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Cache;

beforeEach(function () {
    // Use null Scout driver — Meilisearch calls return empty results gracefully
    config(['scout.driver' => 'null']);

    // ArtworkService is not final so it can be mocked
    $artworksMock = Mockery::mock(ArtworkService::class);
    $artworksMock->shouldReceive('getFeaturedArtworks')
        ->andReturn(new LengthAwarePaginator(collect(), 0, 1))
        ->byDefault();
    $artworksMock->shouldReceive('getFeaturedArtworkWinner')
        ->andReturn(null)
        ->byDefault();
    app()->instance(ArtworkService::class, $artworksMock);
});

// ── Route integration ─────────────────────────────────────────────────────────

it('home page renders 200 for guests', function () {
    $this->get('/')->assertStatus(200);
});

it('home page renders 200 for authenticated users', function () {
    $this->actingAs(User::factory()->create())
        ->get('/')
        ->assertStatus(200);
});

// ── HomepageService section shape ─────────────────────────────────────────────

it('guest homepage has expected sections but no from_following', function () {
    $sections = app(HomepageService::class)->all();

    expect($sections)->toHaveKeys(['hero', 'trending', 'fresh', 'tags', 'creators', 'news']);
    expect($sections)->not->toHaveKey('from_following');
    expect($sections)->not->toHaveKey('by_tags');
    expect($sections)->not->toHaveKey('by_categories');
});

it('authenticated homepage contains all personalised sections', function () {
    $user     = User::factory()->create();
    $sections = app(HomepageService::class)->allForUser($user);

    expect($sections)->toHaveKeys([
        'hero',
        'from_following',
        'trending',
        'by_tags',
        'by_categories',
        'tags',
        'creators',
        'news',
        'preferences',
    ]);
});

it('preferences section exposes top_tags and top_categories arrays', function () {
    $user     = User::factory()->create();
    $sections = app(HomepageService::class)->allForUser($user);

    expect($sections['preferences'])->toHaveKeys(['top_tags', 'top_categories']);
    expect($sections['preferences']['top_tags'])->toBeArray();
    expect($sections['preferences']['top_categories'])->toBeArray();
});

it('guest and auth homepages have different key sets', function () {
    $user = User::factory()->create();

    $guest = array_keys(app(HomepageService::class)->all());
    $auth  = array_keys(app(HomepageService::class)->allForUser($user));

    expect($guest)->not->toEqual($auth);
    expect(in_array('from_following', $auth))->toBeTrue();
    expect(in_array('from_following', $guest))->toBeFalse();
});

it('homepage artwork payload uses group name and avatar for group-published artworks', function () {
    $owner = User::factory()->create();
    $group = Group::factory()->create([
        'owner_user_id' => $owner->id,
        'name' => 'Skinbase Collective',
        'slug' => 'skinbase-collective',
    ]);

    Artwork::factory()->create([
        'user_id' => $owner->id,
        'group_id' => $group->id,
        'published_as_type' => Artwork::PUBLISHED_AS_GROUP,
        'title' => 'Group Published Artwork',
        'hash' => 'homepagegroupartwork',
        'thumb_ext' => 'webp',
        'published_at' => now()->subMinute(),
    ]);

    Cache::flush();

    $items = app(HomepageService::class)->getFreshUploads(10);

    expect($items)->not->toBeEmpty()
        ->and($items[0]['author'])->toBe('Skinbase Collective')
        ->and($items[0]['author_username'])->toBe('')
        ->and($items[0]['published_as_type'])->toBe(Artwork::PUBLISHED_AS_GROUP)
        ->and($items[0]['publisher']['type'])->toBe('group')
        ->and($items[0]['publisher']['name'])->toBe('Skinbase Collective')
        ->and($items[0]['publisher']['profile_url'])->toContain('/groups/skinbase-collective');
});
