<?php

namespace Tests\Feature\Catalog;

use App\Domains\Catalog\Enums\GroupLayout;
use App\Domains\Catalog\Enums\ProductLayout;
use App\Domains\Catalog\Models\CatalogItem;
use App\Domains\Catalog\Models\Category;
use App\Domains\Catalog\Models\Inventory;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class CategoryDetailTest extends TestCase
{
    use RefreshDatabase;

    public function test_it_returns_category_products_paginated_with_the_tenant_search_layout(): void
    {
        $tenant = $this->createTenant('category-detail');
        $tenant->update([
            'search_product_layout' => ProductLayout::Row->value,
            'search_group_layout' => GroupLayout::SimpleVertical->value,
            'search_items_per_page' => 2,
        ]);
        $category = $this->createCategory($tenant, 'Remeras');
        $otherCategory = $this->createCategory($tenant, 'Pantalones');

        $this->createCatalogItem($tenant, $category, 'Remera C');
        $firstItem = $this->createCatalogItem($tenant, $category, 'Remera A');
        $secondItem = $this->createCatalogItem($tenant, $category, 'Remera B');
        $outOfStock = CatalogItem::query()->create([
            'tenant_code' => $tenant->codigo,
            'category_id' => $category->id,
            'slug' => 'remera-agotada',
            'nombre' => 'Remera agotada',
            'descripcion' => 'Sin stock',
            'precio' => 100,
        ]);
        $outOfStock->variants()->create([
            'inventory_id' => Inventory::query()->create(['real_stock' => 0])->id,
        ]);
        $this->createCatalogItem($tenant, $otherCategory, 'Pantalón');

        $this->getJson("/api/tenants/{$tenant->codigo}/categories/{$category->id}")
            ->assertOk()
            ->assertJsonPath('category.id', $category->id)
            ->assertJsonPath('category.nombre', 'Remeras')
            ->assertJsonPath('category.categoria_id', null)
            ->assertJsonPath('layout', ProductLayout::Row->value)
            ->assertJsonPath('group_layout', GroupLayout::SimpleVertical->value)
            ->assertJsonPath('meta.current_page', 1)
            ->assertJsonPath('meta.per_page', 2)
            ->assertJsonPath('meta.total', 3)
            ->assertJsonCount(2, 'data')
            ->assertJsonPath('data.0.id', $firstItem->id)
            ->assertJsonPath('data.1.id', $secondItem->id)
            ->assertJsonMissing(['nombre' => 'Remera agotada'])
            ->assertJsonMissing(['nombre' => 'Pantalón']);
    }

    public function test_it_returns_an_empty_paginated_response_for_a_category_without_products(): void
    {
        $tenant = $this->createTenant('empty-category');
        $category = $this->createCategory($tenant, 'Sin productos');

        $this->getJson("/api/tenants/{$tenant->codigo}/categories/{$category->id}")
            ->assertOk()
            ->assertJsonPath('category.id', $category->id)
            ->assertJsonPath('meta.total', 0)
            ->assertJsonPath('meta.current_page', 1)
            ->assertJsonCount(0, 'data');
    }

    public function test_it_rejects_categories_from_another_tenant(): void
    {
        $tenant = $this->createTenant('category-owner');
        $otherTenant = $this->createTenant('category-foreign');
        $foreignCategory = $this->createCategory($otherTenant, 'Ajena');

        $this->getJson("/api/tenants/{$tenant->codigo}/categories/{$foreignCategory->id}")
            ->assertNotFound();
    }

    public function test_it_validates_the_page(): void
    {
        $tenant = $this->createTenant('category-page');
        $category = $this->createCategory($tenant, 'Remeras');

        $this->getJson("/api/tenants/{$tenant->codigo}/categories/{$category->id}?page=0")
            ->assertUnprocessable()
            ->assertJsonValidationErrors('page');
    }

    private function createTenant(string $code): Tenant
    {
        return Tenant::query()->create([
            'codigo' => $code,
            'nombre' => ucfirst($code),
            'dominio' => "{$code}.local",
            'primary_color' => '#000000',
            'secondary_color' => '#000000',
            'danger_color' => '#000000',
            'success_color' => '#000000',
            'header_bg_color' => '#000000',
            'footer_bg_color' => '#000000',
        ]);
    }

    private function createCategory(Tenant $tenant, string $name): Category
    {
        return Category::query()->create([
            'tenant_code' => $tenant->codigo,
            'nombre' => $name,
        ]);
    }

    private function createCatalogItem(
        Tenant $tenant,
        Category $category,
        string $name,
    ): CatalogItem {
        $inventory = Inventory::query()->create(['real_stock' => 10]);

        return CatalogItem::query()->create([
            'tenant_code' => $tenant->codigo,
            'category_id' => $category->id,
            'inventory_id' => $inventory->id,
            'slug' => str($name)->slug()->toString(),
            'nombre' => $name,
            'descripcion' => "{$name} description",
            'precio' => 100,
        ]);
    }
}
