<?php

namespace App\Domains\Catalog\Controllers;

use App\Domains\Catalog\Models\Category;
use App\Domains\Catalog\Requests\StoreCategoryRequest;
use App\Domains\Catalog\Requests\UpdateCategoryRequest;
use App\Domains\Catalog\Resources\CategoryResource;
use App\Domains\Tenant\Models\Tenant;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class CategoryController extends Controller
{
    public function index(Tenant $tenant): JsonResponse
    {
        return CategoryResource::collection(
            Category::query()
                ->where(function ($query) use ($tenant): void {
                    $query
                        ->where('tenant_code', $tenant->codigo)
                        ->orWhereNull('tenant_code');
                })
                ->with(['parent', 'subCategories', 'tenant'])
                ->orderByDesc('id')
                ->get()
        )->response();
    }

    public function store(StoreCategoryRequest $request, Tenant $tenant): JsonResponse
    {
        $category = Category::query()->create([
            ...$request->validated(),
            'tenant_code' => $tenant->codigo,
        ]);

        return CategoryResource::make($category->load(['parent', 'subCategories', 'tenant']))
            ->response()
            ->setStatusCode(201);
    }

    public function show(Tenant $tenant, Category $categoria): CategoryResource
    {
        $categoria = $this->resolveScopedCategory($tenant, $categoria);

        return CategoryResource::make($categoria->load(['parent', 'subCategories', 'tenant']));
    }

    public function update(UpdateCategoryRequest $request, Tenant $tenant, Category $categoria): CategoryResource
    {
        $categoria = $this->resolveScopedCategory($tenant, $categoria);
        $this->ensureCategoryIsMutable($categoria);
        $categoria->update($request->validated());

        return CategoryResource::make($categoria->load(['parent', 'subCategories', 'tenant']));
    }

    public function destroy(Tenant $tenant, Category $categoria): Response
    {
        $categoria = $this->resolveScopedCategory($tenant, $categoria);
        $this->ensureCategoryIsMutable($categoria);
        $categoria->delete();

        return response()->noContent();
    }

    protected function resolveScopedCategory(Tenant $tenant, Category $category): Category
    {
        if ($category->tenant_code !== null && $category->tenant_code !== $tenant->codigo) {
            throw new NotFoundHttpException('Category not found for tenant.');
        }

        return $category;
    }

    protected function ensureCategoryIsMutable(Category $category): void
    {
        if ($category->isGlobal()) {
            throw new AccessDeniedHttpException('Global categories are read-only.');
        }
    }
}
