<?php

namespace App\Modules\Inventory\Controllers;

use App\Http\Controllers\Controller;
use App\Http\Responses\ApiResponse;
use App\Modules\Inventory\Models\Category;
use App\Modules\Inventory\Requests\StoreCategoryRequest;
use App\Modules\Inventory\Requests\UpdateCategoryRequest;
use App\Modules\Inventory\Resources\CategoryResource;
use App\Modules\Tenant\Models\Company;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class CategoryController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $company = $this->currentCompany($request);

        $categories = Category::query()
            ->where('company_id', $company->id)
            ->when($request->filled('status'), function ($query) use ($request): void {
                $query->where('status', $request->string('status')->toString());
            })
            ->orderBy('name')
            ->get();

        return ApiResponse::success(CategoryResource::collection($categories));
    }

    public function store(StoreCategoryRequest $request): JsonResponse
    {
        $company = $this->currentCompany($request);
        $data = $request->validated();

        $category = Category::query()->create([
            'company_id' => $company->id,
            'name' => $data['name'],
            'slug' => $this->uniqueSlug($company, $data['name']),
            'status' => $data['status'] ?? 'active',
        ]);

        return ApiResponse::success(new CategoryResource($category), 'Category created successfully', 201);
    }

    public function update(UpdateCategoryRequest $request, Category $category): JsonResponse
    {
        $company = $this->currentCompany($request);

        if ((int) $category->company_id !== (int) $company->id) {
            return ApiResponse::error('Category not found', 404);
        }

        $data = $request->validated();

        if (array_key_exists('name', $data) && $data['name'] !== $category->name) {
            $data['slug'] = $this->uniqueSlug($company, $data['name'], $category->id);
        }

        $category->update($data);

        return ApiResponse::success(new CategoryResource($category->fresh()), 'Category updated successfully');
    }

    private function uniqueSlug(Company $company, string $name, ?int $ignoreCategoryId = null): string
    {
        $baseSlug = Str::slug($name) ?: 'category';
        $slug = $baseSlug;
        $counter = 2;

        while (
            Category::query()
                ->where('company_id', $company->id)
                ->where('slug', $slug)
                ->when($ignoreCategoryId, function ($query) use ($ignoreCategoryId): void {
                    $query->whereKeyNot($ignoreCategoryId);
                })
                ->exists()
        ) {
            $slug = "{$baseSlug}-{$counter}";
            $counter++;
        }

        return $slug;
    }

    private function currentCompany(Request $request): Company
    {
        return $request->attributes->get('currentCompany');
    }
}
