<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;
use App\Models\Post;
use App\Models\Group;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;

class UnifiedSearchTest extends TestCase
{
    use RefreshDatabase;

    protected $user;

    protected function setUp(): void
    {
        parent::setUp();
        
        // Create a test user
        $this->user = User::factory()->create([
            'username' => 'testuser',
            'first_name' => 'John',
            'last_name' => 'Doe',
            'email' => 'john@example.com',
            'status' => 1,
        ]);

        // Authenticate the user
        Sanctum::actingAs($this->user);
    }

    /** @test */
    public function it_can_search_across_all_content_types()
    {
        // Create test data
        $user2 = User::factory()->create([
            'username' => 'techguru',
            'first_name' => 'Tech',
            'last_name' => 'Guru',
            'status' => 1,
        ]);

        $post = Post::factory()->create([
            'user_id' => $this->user->id,
            'post_text' => 'This is a technology post about AI',
            'privacy_level' => 1,
            'status' => 1,
        ]);

        $group = Group::factory()->create([
            'name' => 'Technology Enthusiasts',
            'description' => 'A group for tech lovers',
            'privacy' => 'public',
            'creator_id' => $this->user->id,
        ]);

        $response = $this->getJson('/api/search?query=technology&type=all');

        $response->assertStatus(200)
                ->assertJsonStructure([
                    'status',
                    'message',
                    'data' => [
                        'query',
                        'results' => [
                            'users',
                            'posts',
                            'groups'
                        ],
                        'meta' => [
                            'total_users',
                            'total_posts',
                            'total_groups',
                            'total_results',
                            'search_type',
                            'applied_filters'
                        ]
                    ]
                ]);
    }

    /** @test */
    public function it_can_search_users_only()
    {
        $user2 = User::factory()->create([
            'username' => 'techguru',
            'first_name' => 'Tech',
            'last_name' => 'Guru',
            'status' => 1,
        ]);

        $response = $this->getJson('/api/search?query=tech&type=users');

        $response->assertStatus(200)
                ->assertJsonPath('data.results.users.0.username', 'techguru');
    }

    /** @test */
    public function it_can_search_posts_only()
    {
        $post = Post::factory()->create([
            'user_id' => $this->user->id,
            'post_text' => 'This is a technology post',
            'privacy_level' => 1,
            'status' => 1,
        ]);

        $response = $this->getJson('/api/search?query=technology&type=posts');

        $response->assertStatus(200)
                ->assertJsonPath('data.results.posts.0.post_text', 'This is a technology post');
    }

    /** @test */
    public function it_can_search_groups_only()
    {
        $group = Group::factory()->create([
            'name' => 'Technology Group',
            'description' => 'A tech group',
            'privacy' => 'public',
            'creator_id' => $this->user->id,
        ]);

        $response = $this->getJson('/api/search?query=technology&type=groups');

        $response->assertStatus(200)
                ->assertJsonPath('data.results.groups.0.name', 'Technology Group');
    }

    /** @test */
    public function it_provides_autocomplete_suggestions()
    {
        $user2 = User::factory()->create([
            'username' => 'techguru',
            'first_name' => 'Tech',
            'last_name' => 'Guru',
            'status' => 1,
        ]);

        $response = $this->getJson('/api/search/autocomplete?query=tech');

        $response->assertStatus(200)
                ->assertJsonStructure([
                    'status',
                    'message',
                    'data' => [
                        '*' => [
                            'type',
                            'id',
                            'title',
                            'subtitle'
                        ]
                    ]
                ]);
    }

    /** @test */
    public function it_returns_trending_searches()
    {
        $response = $this->getJson(base_url+'/api/search/trending');

        $response->assertStatus(200)
                ->assertJsonStructure([
                    'status',
                    'message',
                    'data' => [
                        '*' => [
                            'query',
                            'count'
                        ]
                    ]
                ]);
    }

    /** @test */
    public function it_validates_search_parameters()
    {
        // Test missing query parameter
        $response = $this->getJson('/api/search');
        $response->assertStatus(422);

        // Test invalid type parameter
        $response = $this->getJson('/api/search?query=test&type=invalid');
        $response->assertStatus(422);

        // Test invalid limit parameter
        $response = $this->getJson('/api/search?query=test&limit=100');
        $response->assertStatus(422);
    }

    /** @test */
    public function it_applies_privacy_filters_for_posts()
    {
        // Create a private post from another user
        $otherUser = User::factory()->create(['status' => 1]);
        $privatePost = Post::factory()->create([
            'user_id' => $otherUser->id,
            'post_text' => 'This is a private technology post',
            'privacy_level' => 3, // Only me
            'status' => 1,
        ]);

        // Create a public post
        $publicPost = Post::factory()->create([
            'user_id' => $otherUser->id,
            'post_text' => 'This is a public technology post',
            'privacy_level' => 1, // Public
            'status' => 1,
        ]);

        $response = $this->getJson('/api/search?query=technology&type=posts');

        $response->assertStatus(200);
        
        // Should only return the public post
        $posts = $response->json('data.results.posts');
        $this->assertCount(1, $posts);
        $this->assertEquals('This is a public technology post', $posts[0]['post_text']);
    }

    /** @test */
    public function it_applies_sorting_correctly()
    {
        // Create users with different creation dates
        $user1 = User::factory()->create([
            'username' => 'tech1',
            'first_name' => 'Tech',
            'last_name' => 'One',
            'status' => 1,
            'created_at' => now()->subDays(2),
        ]);

        $user2 = User::factory()->create([
            'username' => 'tech2',
            'first_name' => 'Tech',
            'last_name' => 'Two',
            'status' => 1,
            'created_at' => now()->subDays(1),
        ]);

        // Test date sorting (newest first)
        $response = $this->getJson('/api/search?query=tech&type=users&sort_by=date');
        $response->assertStatus(200);
        
        $users = $response->json('data.results.users');
        $this->assertEquals('tech2', $users[0]['username']);

        // Test alphabetical sorting
        $response = $this->getJson('/api/search?query=tech&type=users&sort_by=alphabetical');
        $response->assertStatus(200);
        
        $users = $response->json('data.results.users');
        $this->assertEquals('tech1', $users[0]['username']); // "One" comes before "Two"
    }

    /** @test */
    public function it_applies_filters_correctly()
    {
        // Create users with different verification status
        $verifiedUser = User::factory()->create([
            'username' => 'verified_tech',
            'first_name' => 'Verified',
            'last_name' => 'Tech',
            'status' => 1,
            'email_verified_at' => now(),
        ]);

        $unverifiedUser = User::factory()->create([
            'username' => 'unverified_tech',
            'first_name' => 'Unverified',
            'last_name' => 'Tech',
            'status' => 1,
            'email_verified_at' => null,
        ]);

        // Test verified only filter
        $response = $this->getJson('/api/search?query=tech&type=users&filters[verified_only]=true');
        $response->assertStatus(200);
        
        $users = $response->json('data.results.users');
        $this->assertCount(1, $users);
        $this->assertEquals('verified_tech', $users[0]['username']);
    }

    /** @test */
    public function it_handles_pagination_correctly()
    {
        // Create multiple users
        for ($i = 1; $i <= 25; $i++) {
            User::factory()->create([
                'username' => "tech_user_{$i}",
                'first_name' => 'Tech',
                'last_name' => "User{$i}",
                'status' => 1,
            ]);
        }

        // Test first page
        $response = $this->getJson('/api/search?query=tech&type=users&limit=10&offset=0');
        $response->assertStatus(200);
        
        $users = $response->json('data.results.users');
        $this->assertCount(10, $users);

        // Test second page
        $response = $this->getJson('/api/search?query=tech&type=users&limit=10&offset=10');
        $response->assertStatus(200);
        
        $users = $response->json('data.results.users');
        $this->assertCount(10, $users);
    }
} 