<?php

use App\Models\Artwork;
use App\Http\Controllers\Web\DiscoverController;
use App\Services\ArtworkService;
use Illuminate\Pagination\LengthAwarePaginator;

beforeEach(function () {
    $this->artworksMock = Mockery::mock(ArtworkService::class);
    $this->artworksMock->shouldReceive('getFeaturedArtworks')
        ->andReturn(new LengthAwarePaginator(collect(), 0, 20, 1))
        ->byDefault();
    $this->artworksMock->shouldReceive('getLatestArtworks')
        ->andReturn(collect())
        ->byDefault();
    $this->artworksMock->shouldReceive('getFeaturedArtworkWinner')
        ->andReturn(null)
        ->byDefault();
    $this->app->instance(ArtworkService::class, $this->artworksMock);
});

it('GET /discover/rising returns 200', function () {
    $this->get('/discover/rising')
        ->assertStatus(200);
});

it('/discover/rising page contains Rising Now heading', function () {
    $this->get('/discover/rising')
        ->assertStatus(200)
        ->assertSee('Rising Now', false);
});

it('/discover/rising page includes the rising section pill as active', function () {
    $this->get('/discover/rising')
        ->assertStatus(200)
        ->assertSee('bg-sky-600', false);
});

it('GET /discover/trending still returns 200', function () {
    $this->get('/discover/trending')
        ->assertStatus(200);
});

it('drops stale private artworks during discover search hydration', function () {
    $visibleArtwork = Artwork::withoutEvents(fn () => Artwork::factory()->create([
        'title' => 'Visible Trending Artwork',
        'is_public' => true,
        'visibility' => Artwork::VISIBILITY_PUBLIC,
        'is_approved' => true,
        'published_at' => now()->subHour(),
    ]));

    $privateArtwork = Artwork::withoutEvents(fn () => Artwork::factory()->create([
        'title' => 'Private Trending Artwork',
        'is_public' => true,
        'visibility' => Artwork::VISIBILITY_PRIVATE,
        'is_approved' => true,
        'published_at' => now()->subHour(),
    ]));

    $controller = app(DiscoverController::class);
    $method = new ReflectionMethod($controller, 'hydrateDiscoverSearchResults');
    $method->setAccessible(true);

    $paginator = new LengthAwarePaginator(
        collect([
            (object) ['id' => $visibleArtwork->id, 'title' => $visibleArtwork->title],
            (object) ['id' => $privateArtwork->id, 'title' => $privateArtwork->title],
        ]),
        2,
        24,
        1
    );

    $method->invoke($controller, $paginator);

    expect($paginator->getCollection()->pluck('id')->all())->toBe([$visibleArtwork->id]);
    expect($paginator->getCollection()->pluck('name')->all())->toBe(['Visible Trending Artwork']);
});

it('excludes private and unpublished artworks from trending database fallback', function () {
    $visibleArtwork = Artwork::withoutEvents(fn () => Artwork::factory()->create([
        'title' => 'Visible Fallback Artwork',
        'is_public' => true,
        'visibility' => Artwork::VISIBILITY_PUBLIC,
        'is_approved' => true,
        'published_at' => now()->subHours(2),
    ]));

    $privateArtwork = Artwork::withoutEvents(fn () => Artwork::factory()->create([
        'title' => 'Private Fallback Artwork',
        'is_public' => true,
        'visibility' => Artwork::VISIBILITY_PRIVATE,
        'is_approved' => true,
        'published_at' => now()->subHours(2),
    ]));

    $scheduledArtwork = Artwork::withoutEvents(fn () => Artwork::factory()->create([
        'title' => 'Scheduled Fallback Artwork',
        'is_public' => true,
        'visibility' => Artwork::VISIBILITY_PUBLIC,
        'is_approved' => true,
        'published_at' => now()->addDay(),
    ]));

    $controller = app(DiscoverController::class);
    $method = new ReflectionMethod($controller, 'fallbackTrendingFromDatabase');
    $method->setAccessible(true);

    $paginator = $method->invoke($controller, 24, 30);
    $ids = $paginator->getCollection()->pluck('id')->all();

    expect($ids)->toContain($visibleArtwork->id);
    expect($ids)->not->toContain($privateArtwork->id);
    expect($ids)->not->toContain($scheduledArtwork->id);
});

it('home page still renders with rising section data', function () {
    $this->get('/')
        ->assertStatus(200);
});

it('uses the low-signal fallback ordering when rising search results have no momentum', function () {
    $olderArtwork = Artwork::withoutEvents(fn () => Artwork::factory()->create([
        'title' => 'Older Fallback Artwork',
        'is_public' => true,
        'is_approved' => true,
        'published_at' => now()->subDays(4),
        'created_at' => now()->subDays(4),
    ]));

    $newerArtwork = Artwork::withoutEvents(fn () => Artwork::factory()->create([
        'title' => 'Newer Fallback Artwork',
        'is_public' => true,
        'is_approved' => true,
        'published_at' => now()->subHour(),
        'created_at' => now()->subHour(),
    ]));

    $this->get('/discover/rising')
        ->assertStatus(200)
        ->assertSeeInOrder(['Newer Fallback Artwork', 'Older Fallback Artwork'], false);
});
