<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreInventoryProductRequest;
use App\Http\Requests\UpdateInventoryProductRequest;
use App\Http\Controllers\Concerns\DestroysCatalogItem;
use App\Models\InventoryProduct;
use App\Support\CatalogDeletionGuard;
use App\Support\CatalogCodeGenerator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class InventoryProductController extends Controller
{
    use DestroysCatalogItem;

    public function index(Request $request): JsonResponse
    {
        $perPage = min(100, max(5, (int) $request->get('per_page', 20)));

        $query = InventoryProduct::query()
            ->with(['productType', 'brand', 'category', 'subcategory', 'supplier']);

        if ($request->filled('q')) {
            $term = $request->get('q');
            $query->where(function ($w) use ($term): void {
                $w->where('sku', 'like', '%'.$term.'%')
                    ->orWhere('name', 'like', '%'.$term.'%');
            });
        }

        if ($request->has('active') && $request->get('active') !== '' && $request->get('active') !== null) {
            $query->where('active', filter_var($request->get('active'), FILTER_VALIDATE_BOOLEAN));
        }

        return response()->json([
            'data' => $query->orderBy('sku')->paginate($perPage),
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    public function store(StoreInventoryProductRequest $request): JsonResponse
    {
        $data = $request->validated();
        $data['sku'] = CatalogCodeGenerator::resolve(
            $data['sku'] ?? null,
            $data['name'],
            InventoryProduct::class,
            'sku',
            'inv',
            prefix: 'inv',
        );
        $data['stock_quantity'] = '0';
        $data['active'] = $data['active'] ?? true;

        $product = InventoryProduct::query()->create($data);

        return response()->json([
            'data' => $product->load(['productType', 'brand', 'category', 'subcategory', 'supplier']),
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_CREATED);
    }

    public function show(InventoryProduct $inventory_product): JsonResponse
    {
        return response()->json([
            'data' => $inventory_product->load(['productType', 'brand', 'category', 'subcategory', 'supplier']),
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    public function update(UpdateInventoryProductRequest $request, InventoryProduct $inventory_product): JsonResponse
    {
        $inventory_product->fill($request->validated());
        $inventory_product->save();

        return response()->json([
            'data' => $inventory_product->fresh()->load(['productType', 'brand', 'category', 'subcategory', 'supplier']),
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    public function destroy(InventoryProduct $inventory_product): JsonResponse
    {
        return $this->destroyCatalogItem(
            CatalogDeletionGuard::inventoryProduct($inventory_product),
            fn () => $inventory_product->delete(),
        );
    }

    public function activate(InventoryProduct $inventory_product): JsonResponse
    {
        $inventory_product->active = true;
        $inventory_product->save();

        return response()->json([
            'data' => $inventory_product->fresh()->load(['productType', 'brand', 'category', 'subcategory', 'supplier']),
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    public function disable(InventoryProduct $inventory_product): JsonResponse
    {
        $inventory_product->active = false;
        $inventory_product->save();

        return response()->json([
            'data' => $inventory_product->fresh()->load(['productType', 'brand', 'category', 'subcategory', 'supplier']),
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }
}
