<?php

namespace Tests\Feature;

use App\Models\Advertisement;
use App\Models\Category;
use App\Models\Product;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;

class HomeApiTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        Cache::flush();
    }

    public function test_home_api_returns_correct_structure(): void
    {
        // Create root categories with children
        $rootCategory1 = Category::factory()->create(['parent_id' => null, 'status' => 'active']);
        $childCategory1 = Category::factory()->create(['parent_id' => $rootCategory1->id, 'status' => 'active']);
        $childCategory2 = Category::factory()->create(['parent_id' => $rootCategory1->id, 'status' => 'active']);

        $rootCategory2 = Category::factory()->create(['parent_id' => null, 'status' => 'active']);
        $childCategory3 = Category::factory()->create(['parent_id' => $rootCategory2->id, 'status' => 'active']);

        // Create an inactive category (should not appear)
        Category::factory()->create(['parent_id' => null, 'status' => 'inactive']);

        // Create products for each category
        Product::factory()->count(5)->create(['category_id' => $rootCategory1->id]);
        Product::factory()->count(3)->create(['category_id' => $childCategory1->id]);
        Product::factory()->count(4)->create(['category_id' => $childCategory2->id]);
        Product::factory()->count(6)->create(['category_id' => $rootCategory2->id]);
        Product::factory()->count(2)->create(['category_id' => $childCategory3->id]);

        // Create active and inactive ads
        Advertisement::factory()->create([
            'status' => 'active',
            'start_date' => now()->subDay(),
            'end_date' => now()->addWeek(),
        ]);

        Advertisement::factory()->create([
            'status' => 'inactive',
        ]);

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

        $response->assertStatus(200)
            ->assertJsonStructure([
                'categories' => [
                    '*' => [
                        'id',
                        'name_en',
                        'name_ar',
                        'slug',
                        'description_en',
                        'description_ar',
                        'image',
                        'icon',
                        'status',
                        'meta_title',
                        'meta_description',
                        'subcategories' => [
                            '*' => [
                                'id',
                                'name_en',
                                'name_ar',
                                'slug',
                                'icon',
                            ],
                        ],
                        'products' => [
                            '*' => [
                                'id',
                                'source',
                                'image_url',
                                'video_url',
                                'name_ar',
                                'name_en',
                                'description_ar',
                                'description_en',
                                'price',
                                'discount_price',
                                'discount',
                                'currency',
                                'positive_feedback',
                                'sales_180day',
                                'promotion_url',
                            ],
                        ],
                    ],
                ],
                'advertisements' => [
                    '*' => [
                        'id',
                        'title',
                        'title_ar',
                        'image_url',
                        'link',
                    ],
                ],
            ]);
    }

    public function test_home_api_limits_products_to_8_per_category(): void
    {
        Cache::flush();

        $rootCategory = Category::factory()->create(['parent_id' => null, 'status' => 'active']);
        $childCategory = Category::factory()->create(['parent_id' => $rootCategory->id, 'status' => 'active']);

        // Create more than 8 products
        Product::factory()->count(8)->create(['category_id' => $rootCategory->id]);
        Product::factory()->count(5)->create(['category_id' => $childCategory->id]);

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

        $response->assertStatus(200);

        $data = $response->json();
        $categoryData = collect($data['categories'])->first(fn ($cat) => $cat['id'] === $rootCategory->id);

        // Should have max 8 products (from parent + children combined)
        $this->assertLessThanOrEqual(8, count($categoryData['products']));
    }

    public function test_home_api_includes_products_from_subcategories(): void
    {
        Cache::flush();

        $rootCategory = Category::factory()->create(['parent_id' => null, 'status' => 'active']);
        $childCategory = Category::factory()->create(['parent_id' => $rootCategory->id, 'status' => 'active']);

        // Create products for each
        $rootProduct = Product::factory()->create(['category_id' => $rootCategory->id, 'name_en' => 'Root Product']);
        $childProduct = Product::factory()->create(['category_id' => $childCategory->id, 'name_en' => 'Child Product']);

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

        $response->assertStatus(200);

        $data = $response->json();
        $categoryData = collect($data['categories'])->first(fn ($cat) => $cat['id'] === $rootCategory->id);
        $productNames = collect($categoryData['products'])->pluck('name_en');

        $this->assertContains('Root Product', $productNames);
        $this->assertContains('Child Product', $productNames);
    }

    public function test_home_api_caches_response(): void
    {
        Cache::flush();

        Category::factory()->create(['parent_id' => null, 'status' => 'active']);

        // First call - should execute queries and cache
        $response1 = $this->getJson('/api/v1/home');
        $response1->assertStatus(200);

        // Second call - should return cached result
        $response2 = $this->getJson('/api/v1/home');
        $response2->assertStatus(200);

        // Responses should be identical
        $this->assertEquals($response1->json(), $response2->json());
    }

    public function test_home_api_returns_only_active_categories(): void
    {
        Cache::flush();

        Category::factory()->create(['parent_id' => null, 'status' => 'active', 'name_en' => 'Active Category']);
        Category::factory()->create(['parent_id' => null, 'status' => 'inactive', 'name_en' => 'Inactive Category']);

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

        $response->assertStatus(200);

        $data = $response->json();
        $categoryNames = collect($data['categories'])->pluck('name_en');

        $this->assertContains('Active Category', $categoryNames);
        $this->assertNotContains('Inactive Category', $categoryNames);
    }

    public function test_home_api_returns_only_active_ads(): void
    {
        Cache::flush();

        Advertisement::factory()->create([
            'status' => 'active',
            'title_en' => 'Active Ad',
            'start_date' => now()->subDay(),
            'end_date' => now()->addWeek(),
        ]);

        Advertisement::factory()->create([
            'status' => 'inactive',
            'title_en' => 'Inactive Ad',
        ]);

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

        $response->assertStatus(200);

        $data = $response->json();
        $adTitles = collect($data['advertisements'])->pluck('title');

        $this->assertContains('Active Ad', $adTitles);
        $this->assertNotContains('Inactive Ad', $adTitles);
    }
}
