<?php

declare(strict_types=1);

use App\Models\Artwork;
use App\Models\Group;
use App\Models\GroupChallenge;
use App\Models\GroupChallengeOutcome;
use App\Models\User;
use App\Models\World;
use App\Models\WorldRewardGrant;
use App\Models\WorldSubmission;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Inertia\Testing\AssertableInertia;

uses(RefreshDatabase::class);

function createPublicWorldForProfileHistory(array $overrides = []): World
{
    return World::factory()->create(array_merge([
        'title' => 'World History ' . strtolower(fake()->bothify('####')),
        'slug' => 'world-history-' . strtolower(fake()->bothify('####')),
        'status' => World::STATUS_PUBLISHED,
        'published_at' => now()->subDay(),
    ], $overrides));
}

function createPublicArtworkForProfileHistory(User $creator, array $overrides = []): Artwork
{
    return Artwork::factory()->for($creator)->create(array_merge([
        'title' => 'World Artwork ' . strtolower(fake()->bothify('####')),
        'slug' => 'world-artwork-' . strtolower(fake()->bothify('####')),
        'artwork_status' => 'published',
        'published_at' => now()->subDay(),
        'is_public' => true,
        'visibility' => Artwork::VISIBILITY_PUBLIC,
        'is_approved' => true,
    ], $overrides));
}

it('exposes normalized world history on public profile pages', function (): void {
    $creator = User::factory()->create([
        'username' => 'worldhist-' . strtolower(fake()->bothify('####')),
    ]);

    $groupOwner = User::factory()->create();
    $group = Group::factory()->create([
        'owner_user_id' => $groupOwner->id,
        'visibility' => Group::VISIBILITY_PUBLIC,
        'status' => Group::LIFECYCLE_ACTIVE,
    ]);

    $challenge = GroupChallenge::query()->create([
        'group_id' => $group->id,
        'title' => 'Autumn Finals',
        'slug' => 'autumn-finals-' . strtolower(fake()->bothify('####')),
        'summary' => 'Final round challenge.',
        'description' => 'Final round challenge.',
        'visibility' => GroupChallenge::VISIBILITY_PUBLIC,
        'participation_scope' => GroupChallenge::PARTICIPATION_PUBLIC,
        'status' => GroupChallenge::STATUS_ACTIVE,
        'start_at' => now()->subDays(2),
        'end_at' => now()->addDays(2),
        'created_by_user_id' => $groupOwner->id,
    ]);

    $world = createPublicWorldForProfileHistory([
        'title' => 'Autumn Finals 2026',
        'slug' => 'autumn-finals-2026-' . strtolower(fake()->bothify('####')),
        'linked_challenge_id' => $challenge->id,
        'recurrence_key' => 'autumn-finals',
        'edition_year' => 2026,
    ]);

    $artwork = createPublicArtworkForProfileHistory($creator, [
        'title' => 'Autumn Skyline',
        'slug' => 'autumn-skyline-' . strtolower(fake()->bothify('####')),
    ]);

    WorldSubmission::query()->create([
        'world_id' => $world->id,
        'artwork_id' => $artwork->id,
        'submitted_by_user_id' => $creator->id,
        'status' => WorldSubmission::STATUS_LIVE,
        'is_featured' => false,
        'reviewed_at' => now()->subDay(),
    ]);

    GroupChallengeOutcome::query()->create([
        'group_challenge_id' => $challenge->id,
        'artwork_id' => $artwork->id,
        'user_id' => $creator->id,
        'outcome_type' => GroupChallengeOutcome::TYPE_WINNER,
        'awarded_by_user_id' => $groupOwner->id,
        'awarded_at' => now()->subHour(),
    ]);

    $this->get(route('profile.show', ['username' => strtolower((string) $creator->username)]))
        ->assertOk()
        ->assertInertia(fn (AssertableInertia $page) => $page
            ->component('Profile/ProfileShow')
            ->where('worldHistory.summary.available', true)
            ->where('worldHistory.summary.world_appearances', 1)
            ->where('worldHistory.summary.worlds_joined', 1)
            ->where('worldHistory.summary.winner_appearances', 1)
            ->where('worldHistory.summary.most_recent_world_activity.primary_recognition.key', 'winner')
            ->where('worldHistory.entries.0.world.title', 'Autumn Finals 2026')
            ->where('worldHistory.entries.0.primary_recognition.key', 'winner')
            ->where('worldHistory.entries.0.recognition_keys.0', 'winner')
            ->where('worldHistory.entries.0.challenge.title', 'Autumn Finals')
            ->where('worldHistory.entries.0.linked_artwork.title', 'Autumn Skyline'));
});

it('filters stale public world rewards while preserving owner-only context counts', function (): void {
    $creator = User::factory()->create([
        'username' => 'worldfilter-' . strtolower(fake()->bothify('####')),
    ]);

    $staleWorld = createPublicWorldForProfileHistory([
        'title' => 'Removed Entry World',
        'slug' => 'removed-entry-world-' . strtolower(fake()->bothify('####')),
    ]);

    $pendingWorld = createPublicWorldForProfileHistory([
        'title' => 'Pending Entry World',
        'slug' => 'pending-entry-world-' . strtolower(fake()->bothify('####')),
    ]);

    $removedArtwork = createPublicArtworkForProfileHistory($creator, [
        'title' => 'Removed Entry Artwork',
        'slug' => 'removed-entry-artwork-' . strtolower(fake()->bothify('####')),
    ]);

    $pendingArtwork = createPublicArtworkForProfileHistory($creator, [
        'title' => 'Pending Entry Artwork',
        'slug' => 'pending-entry-artwork-' . strtolower(fake()->bothify('####')),
    ]);

    $removedSubmission = WorldSubmission::query()->create([
        'world_id' => $staleWorld->id,
        'artwork_id' => $removedArtwork->id,
        'submitted_by_user_id' => $creator->id,
        'status' => WorldSubmission::STATUS_REMOVED,
        'removed_at' => now()->subHour(),
    ]);

    WorldRewardGrant::query()->create([
        'user_id' => $creator->id,
        'world_id' => $staleWorld->id,
        'artwork_id' => $removedArtwork->id,
        'world_submission_id' => $removedSubmission->id,
        'reward_type' => 'participant',
        'grant_source' => 'automatic',
        'granted_at' => now()->subMinutes(30),
    ]);

    WorldSubmission::query()->create([
        'world_id' => $pendingWorld->id,
        'artwork_id' => $pendingArtwork->id,
        'submitted_by_user_id' => $creator->id,
        'status' => WorldSubmission::STATUS_PENDING,
    ]);

    $this->get(route('profile.show', ['username' => strtolower((string) $creator->username)]))
        ->assertOk()
        ->assertInertia(fn (AssertableInertia $page) => $page
            ->component('Profile/ProfileShow')
            ->where('worldHistory.summary.available', false)
            ->where('worldHistory.entries', [])
            ->where('worldHistory.owner_context', null));

    $this->actingAs($creator)
        ->get(route('profile.show', ['username' => strtolower((string) $creator->username)]))
        ->assertOk()
        ->assertInertia(fn (AssertableInertia $page) => $page
            ->component('Profile/ProfileShow')
            ->where('worldHistory.summary.available', false)
            ->where('worldHistory.owner_context.pending_submissions', 1)
            ->where('worldHistory.owner_context.removed_or_blocked_submissions', 1)
            ->where('worldHistory.owner_context.hidden_public_entries', 1));
});

it('supports the canonical worlds profile tab route', function (): void {
    $creator = User::factory()->create([
        'username' => 'worldtab-' . strtolower(fake()->bothify('####')),
    ]);

    $world = createPublicWorldForProfileHistory([
        'title' => 'Featured Worlds 2026',
        'slug' => 'featured-worlds-2026-' . strtolower(fake()->bothify('####')),
        'edition_year' => 2026,
    ]);

    $artwork = createPublicArtworkForProfileHistory($creator, [
        'title' => 'Featured Worlds Artwork',
        'slug' => 'featured-worlds-artwork-' . strtolower(fake()->bothify('####')),
    ]);

    $submission = WorldSubmission::query()->create([
        'world_id' => $world->id,
        'artwork_id' => $artwork->id,
        'submitted_by_user_id' => $creator->id,
        'status' => WorldSubmission::STATUS_LIVE,
        'is_featured' => true,
        'featured_at' => now()->subMinutes(10),
    ]);

    WorldRewardGrant::query()->create([
        'user_id' => $creator->id,
        'world_id' => $world->id,
        'artwork_id' => $artwork->id,
        'world_submission_id' => $submission->id,
        'reward_type' => 'featured',
        'grant_source' => 'automatic',
        'granted_at' => now()->subMinutes(5),
    ]);

    $this->get(route('profile.tab', ['username' => strtolower((string) $creator->username), 'tab' => 'worlds']))
        ->assertOk()
        ->assertInertia(fn (AssertableInertia $page) => $page
            ->component('Profile/ProfileShow')
            ->where('initialTab', 'worlds')
            ->where('profileTabUrls.worlds', url('/@' . strtolower((string) $creator->username) . '/worlds'))
            ->where('worldHistory.summary.available', true)
            ->where('worldHistory.entries.0.primary_recognition.key', 'featured'));
});