<?php

declare(strict_types=1);

namespace App\Framework\Database\Exception;

use App\Framework\Exception\Core\DatabaseErrorCode;
use App\Framework\Exception\ExceptionContext;

/**
 * Entity Not Found Exception
 *
 * Thrown when an entity cannot be found by its identifier.
 * This is typically a 404-like error at the database layer.
 */
final class EntityNotFoundException extends DatabaseException
{
    /**
     * Create exception for entity not found by ID
     *
     * @param string $entityClass Fully qualified entity class name
     * @param mixed $id Entity identifier
     * @param ?\Throwable $previous Previous exception
     */
    public static function byId(string $entityClass, mixed $id, ?\Throwable $previous = null): self
    {
        $message = "Entity '{$entityClass}' with ID '{$id}' not found";

        $context = ExceptionContext::forOperation('entity.find', 'EntityManager')
            ->withData([
                'entity_class' => $entityClass,
                'entity_id' => (string) $id,
                'lookup_type' => 'by_id',
            ]);

        return self::fromContext($message, $context, DatabaseErrorCode::ENTITY_NOT_FOUND, $previous, 404);
    }

    /**
     * Create exception for entity not found by criteria
     *
     * @param string $entityClass Fully qualified entity class name
     * @param array<string, mixed> $criteria Search criteria
     * @param ?\Throwable $previous Previous exception
     */
    public static function byCriteria(string $entityClass, array $criteria, ?\Throwable $previous = null): self
    {
        $criteriaStr = json_encode($criteria);
        $message = "Entity '{$entityClass}' not found with criteria: {$criteriaStr}";

        $context = ExceptionContext::forOperation('entity.find', 'EntityManager')
            ->withData([
                'entity_class' => $entityClass,
                'lookup_type' => 'by_criteria',
            ])
            ->withDebug([
                'criteria' => $criteria,
            ]);

        return self::fromContext($message, $context, DatabaseErrorCode::ENTITY_NOT_FOUND, $previous, 404);
    }

    // No custom constructor - uses parent DatabaseException constructor directly
    // For backward compatibility with old usage, use factory methods:
    // EntityNotFoundException::byId($entityClass, $id) instead of new EntityNotFoundException($entityClass, $id)
}
