<?php

declare(strict_types=1);

namespace apexl\Io\Traits;

use apexl\Io\exceptions\EntityNotFoundException;

/**
 * Trait for controllers that resolve an entity by id and want a 404 when it
 * doesn't exist. Replaces the 4-line:
 *
 *     $entity = X::find($id);
 *     if ($entity === null) {
 *         return $this->json($response, ['error' => 'X not found'], 404);
 *     }
 *
 * ...with:
 *
 *     $entity = $this->findOr404(X::class, $id, 'X');
 *
 * Throws {@see EntityNotFoundException}; caught by
 * {@see \apexl\Io\middleware\EntityNotFoundMiddleware} which converts to JSON
 * `{"error": "X not found"}` with status 404.
 *
 * If a controller needs custom behaviour on miss (e.g. redirect instead of
 * 404, fallback record, etc.) it should keep the explicit if-null path.
 */
trait FindOr404Trait
{
    /**
     * @template T
     * @param class-string<T> $entityClass
     * @return T
     */
    protected function findOr404(string $entityClass, ?int $id, string $label): object
    {
        $entity = $entityClass::find((int) ($id ?? 0));
        if ($entity === null) {
            throw new EntityNotFoundException($label, $id);
        }
        return $entity;
    }
}
