<?php

namespace Tests\Feature;

use App\Models\Artwork;
use App\Models\Category;
use App\Models\ContentType;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class BrowseApiTest extends TestCase
{
    use RefreshDatabase;

    public function test_web_browse_renders_canonical_and_rel_prev_next_for_paginated_pages(): void
    {
        $user = User::factory()->create(['name' => 'Seo Author']);
        $contentType = ContentType::create([
            'name' => 'Skins',
            'slug' => 'skins',
            'description' => 'Skins content type',
        ]);

        $category = Category::create([
            'content_type_id' => $contentType->id,
            'name' => 'Classic',
            'slug' => 'classic',
            'description' => 'Classic skins',
            'is_active' => true,
            'sort_order' => 1,
        ]);

        for ($i = 1; $i <= 25; $i++) {
            $artwork = Artwork::factory()
                ->for($user)
                ->create([
                    'title' => 'Seo Item ' . $i,
                    'slug' => 'seo-item-' . $i,
                    'published_at' => now()->subMinutes($i),
                ]);
            $artwork->categories()->attach($category->id);
        }

        $response = $this->get('/explore?limit=12&grid=v2');
        $response->assertOk();

        $html = $response->getContent();
        $this->assertNotFalse($html);
        $this->assertStringContainsString('name="robots" content="index,follow"', $html);
        $this->assertMatchesRegularExpression('/<link rel="canonical" href="[^"]*\/explore\?limit=12"\s*\/>/i', $html);
        preg_match('/<link rel="canonical" href="([^"]+)"\s*\/>/i', $html, $canonicalMatches);
        $this->assertArrayHasKey(1, $canonicalMatches);
        $canonicalUrl = html_entity_decode((string) $canonicalMatches[1], ENT_QUOTES);
        $this->assertStringNotContainsString('grid=v2', $canonicalUrl);

        $secondPage = $this->get('/explore?limit=12&page=2&grid=v2');
        $secondPage->assertOk();
        $secondHtml = $secondPage->getContent();
        $this->assertNotFalse($secondHtml);
        $this->assertMatchesRegularExpression('/<link rel="canonical" href="[^"]*\/explore\?[^"]*page=2/i', $secondHtml);
        preg_match('/<link rel="canonical" href="([^"]+)"\s*\/>/i', $secondHtml, $secondCanonicalMatches);
        $this->assertArrayHasKey(1, $secondCanonicalMatches);
        $secondCanonicalUrl = html_entity_decode((string) $secondCanonicalMatches[1], ENT_QUOTES);
        $this->assertStringNotContainsString('grid=v2', $secondCanonicalUrl);
        $this->assertStringContainsString('page=2', $secondCanonicalUrl);

        $pageOne = $this->get('/explore?limit=12&page=1&grid=v2');
        $pageOne->assertOk();
        $pageOneHtml = $pageOne->getContent();
        $this->assertNotFalse($pageOneHtml);
        $this->assertMatchesRegularExpression('/<link rel="canonical" href="[^"]*\/explore\?limit=12"\s*\/>/i', $pageOneHtml);
        preg_match('/<link rel="canonical" href="([^"]+)"\s*\/>/i', $pageOneHtml, $pageOneCanonicalMatches);
        $this->assertArrayHasKey(1, $pageOneCanonicalMatches);
        $pageOneCanonicalUrl = html_entity_decode((string) $pageOneCanonicalMatches[1], ENT_QUOTES);
        $this->assertStringNotContainsString('page=1', $pageOneCanonicalUrl);
    }

    public function test_api_browse_supports_limit_and_cursor_pagination(): void
    {
        $user = User::factory()->create(['name' => 'Cursor Author']);

        $contentType = ContentType::create([
            'name' => 'Skins',
            'slug' => 'skins',
            'description' => 'Skins content type',
        ]);

        $category = Category::create([
            'content_type_id' => $contentType->id,
            'name' => 'Winamp',
            'slug' => 'winamp',
            'description' => 'Winamp skins',
            'is_active' => true,
            'sort_order' => 1,
        ]);

        for ($i = 1; $i <= 6; $i++) {
            $artwork = Artwork::factory()
                ->for($user)
                ->create([
                    'title' => 'Cursor Item ' . $i,
                    'slug' => 'cursor-item-' . $i,
                    'published_at' => now()->subMinutes($i),
                ]);

            $artwork->categories()->attach($category->id);
        }

        $first = $this->getJson('/api/v1/browse?limit=2');
        $first->assertOk();
        $first->assertJsonCount(2, 'data');

        $nextCursor = (string) data_get($first->json(), 'links.next', '');
        $this->assertNotEmpty($nextCursor);
        $this->assertStringContainsString('cursor=', $nextCursor);

        $second = $this->getJson($nextCursor);
        $second->assertOk();
        $second->assertJsonCount(2, 'data');

        $firstFirstSlug = data_get($first->json(), 'data.0.slug');
        $secondFirstSlug = data_get($second->json(), 'data.0.slug');
        $this->assertNotSame($firstFirstSlug, $secondFirstSlug);
    }

    public function test_api_browse_returns_public_artworks(): void
    {
        $user = User::factory()->create(['name' => 'Author One']);
        $contentType = ContentType::create([
            'name' => 'Wallpapers',
            'slug' => 'wallpapers',
            'description' => 'Wallpapers content type',
        ]);

        $category = Category::create([
            'content_type_id' => $contentType->id,
            'name' => 'Abstract',
            'slug' => 'abstract',
            'description' => 'Abstract wallpapers',
            'is_active' => true,
            'sort_order' => 1,
        ]);

        $artwork = Artwork::factory()
            ->for($user)
            ->create([
                'slug' => 'neon-city',
                'published_at' => now()->subDay(),
            ]);

        $artwork->categories()->attach($category->id);

        $response = $this->getJson('/api/v1/browse');

        $response->assertOk()
            ->assertJsonPath('data.0.slug', 'neon-city')
            ->assertJsonPath('data.0.category.slug', 'abstract')
            ->assertJsonPath('data.0.author.name', 'Author One');
    }

    public function test_web_browse_shows_artworks(): void
    {
        $user = User::factory()->create(['name' => 'Author Two']);
        $contentType = ContentType::create([
            'name' => 'Photography',
            'slug' => 'photography',
            'description' => 'Photos',
        ]);

        $category = Category::create([
            'content_type_id' => $contentType->id,
            'name' => 'Nature',
            'slug' => 'nature',
            'description' => 'Nature photos',
            'is_active' => true,
            'sort_order' => 1,
        ]);

        $artwork = Artwork::factory()
            ->for($user)
            ->create([
                'title' => 'Forest Light',
                'slug' => 'forest-light',
                'published_at' => now()->subDay(),
            ]);

        $artwork->categories()->attach($category->id);

        $response = $this->get('/explore');

        $response->assertOk();
        $response->assertSee('Forest Light');
        $response->assertSee('Author Two');

        $html = $response->getContent();
        $this->assertNotFalse($html);
        $this->assertStringContainsString('data-react-masonry-gallery', $html);
        $this->assertStringContainsString('data-gallery-type="browse"', $html);
        $this->assertStringContainsString('Forest Light', $html);
    }
}
