<?php

namespace Tests\Feature;

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

class CategoryApiTest extends TestCase
{
    use RefreshDatabase;

    public function test_guest_can_list_all_categories(): void
    {
        Category::factory()->count(15)->create();

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

        $response->assertOk();
        $response->assertJsonStructure([
            'data' => [
                '*' => [
                    'id', 'parent_id', 'name_ar', 'name_en', 'slug',
                    'description_ar', 'description_en', 'image', 'status',
                    'position', 'meta_title', 'meta_description',
                    'children_count',
                    'created_at', 'updated_at',
                ],
            ],
        ]);

        $this->assertCount(15, $response->json('data'));
    }

    public function test_guest_can_paginate_categories(): void
    {
        Category::factory()->count(30)->create();

        $response = $this->getJson('/api/v1/categories?page=2&per_page=10');

        $response->assertOk();
        $response->assertJsonPath('meta.current_page', 2);
        $response->assertJsonPath('meta.per_page', 10);
        $this->assertCount(10, $response->json('data'));
    }

    public function test_guest_can_get_single_category(): void
    {
        $category = Category::factory()->create([
            'name_en' => 'Electronics',
            'name_ar' => 'الإلكترونيات',
            'slug' => 'electronics',
        ]);

        $response = $this->getJson("/api/v1/categories/{$category->id}");

        $response->assertOk();
        $response->assertJsonPath('data.id', $category->id);
        $response->assertJsonPath('data.name_en', 'Electronics');
        $response->assertJsonPath('data.name_ar', 'الإلكترونيات');
        $response->assertJsonStructure([
            'data' => [
                'id', 'parent_id', 'name_ar', 'name_en', 'slug',
                'children', 'children_count',
                'created_at', 'updated_at',
            ],
        ]);
    }

    public function test_guest_cannot_access_nonexistent_category(): void
    {
        $response = $this->getJson('/api/v1/categories/9999');

        $response->assertNotFound();
    }

    public function test_categories_returns_correct_links(): void
    {
        Category::factory()->count(25)->create();

        $response = $this->getJson('/api/v1/categories?per_page=10');

        $response->assertOk();
        $this->assertArrayHasKey('first', $response->json('links'));
        $this->assertArrayHasKey('last', $response->json('links'));
        $this->assertArrayHasKey('next', $response->json('links'));
        $this->assertNotNull($response->json('links.next'));
    }

    public function test_guest_can_get_category_with_parent_and_children(): void
    {
        $parent = Category::factory()->create([
            'name_en' => 'Electronics',
            'parent_id' => null,
        ]);

        $child1 = Category::factory()->create([
            'name_en' => 'Phones',
            'parent_id' => $parent->id,
        ]);

        $child2 = Category::factory()->create([
            'name_en' => 'Laptops',
            'parent_id' => $parent->id,
        ]);

        $response = $this->getJson("/api/v1/categories/{$parent->id}");

        $response->assertOk();
        $response->assertJsonPath('data.id', $parent->id);
        $response->assertJsonPath('data.parent_id', null);
        $response->assertJsonPath('data.children_count', 2);
        $response->assertJsonCount(2, 'data.children');
        $response->assertJsonPath('data.children.0.name_en', 'Phones');
        $response->assertJsonPath('data.children.1.name_en', 'Laptops');
    }

    public function test_guest_can_filter_root_categories_only(): void
    {
        Category::factory()->create(['parent_id' => null, 'name_en' => 'Root 1']);
        Category::factory()->create(['parent_id' => null, 'name_en' => 'Root 2']);

        $parent = Category::factory()->create(['parent_id' => null, 'name_en' => 'Root 3']);
        Category::factory()->create(['parent_id' => $parent->id, 'name_en' => 'Child 1']);

        $response = $this->getJson('/api/v1/categories?only_parents=true');

        $response->assertOk();
        $this->assertCount(3, $response->json('data'));

        foreach ($response->json('data') as $category) {
            $this->assertNull($category['parent_id']);
        }
    }

    public function test_guest_can_filter_categories_by_parent_id(): void
    {
        $parent = Category::factory()->create(['parent_id' => null]);
        $child1 = Category::factory()->create(['parent_id' => $parent->id, 'name_en' => 'Child 1']);
        $child2 = Category::factory()->create(['parent_id' => $parent->id, 'name_en' => 'Child 2']);
        Category::factory()->create(['parent_id' => null, 'name_en' => 'Other Root']);

        $response = $this->getJson("/api/v1/categories?parent_id={$parent->id}");

        $response->assertOk();
        $this->assertCount(2, $response->json('data'));

        foreach ($response->json('data') as $category) {
            $this->assertEquals($parent->id, $category['parent_id']);
        }
    }

    public function test_child_category_includes_parent_information(): void
    {
        $parent = Category::factory()->create([
            'name_en' => 'Electronics',
            'name_ar' => 'الإلكترونيات',
            'slug' => 'electronics',
        ]);

        $child = Category::factory()->create([
            'parent_id' => $parent->id,
            'name_en' => 'Phones',
        ]);

        $response = $this->getJson("/api/v1/categories/{$child->id}");

        $response->assertOk();
        $response->assertJsonPath('data.parent.id', $parent->id);
        $response->assertJsonPath('data.parent.name_en', 'Electronics');
        $response->assertJsonPath('data.parent.slug', 'electronics');
    }
}
