<?php

declare(strict_types=1);

namespace App\Framework\Database\Repository;

use App\Framework\Database\EntityManager;

/**
 * Basis-Repository für Entities
 */
abstract class EntityRepository
{
    protected string $entityClass;

    public function __construct(
        protected EntityManager $entityManager
    ) {
        if (!isset($this->entityClass)) {
            throw new \LogicException(static::class . " must define \$entityClass property");
        }
    }

    /**
     * Findet Entity nach ID
     */
    public function find(string $id): ?object
    {
        return $this->entityManager->find($this->entityClass, $id);
    }

    /**
     * Findet Entity nach ID (eager loading)
     */
    public function findEager(string $id): ?object
    {
        return $this->entityManager->findEager($this->entityClass, $id);
    }

    /**
     * Findet alle Entities
     */
    public function findAll(): array
    {
        return $this->entityManager->findAll($this->entityClass);
    }

    /**
     * Findet alle Entities (eager loading)
     */
    public function findAllEager(): array
    {
        return $this->entityManager->findAllEager($this->entityClass);
    }

    /**
     * Findet Entities nach Kriterien
     */
    public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null): array
    {
        return $this->entityManager->findBy($this->entityClass, $criteria, $orderBy, $limit);
    }

    /**
     * Findet eine Entity nach Kriterien
     */
    public function findOneBy(array $criteria): ?object
    {
        return $this->entityManager->findOneBy($this->entityClass, $criteria);
    }

    /**
     * Speichert eine Entity
     */
    public function save(object $entity): object
    {
        return $this->entityManager->save($entity);
    }

    /**
     * Speichert mehrere Entities
     */
    public function saveAll(array $entities): array
    {
        return $this->entityManager->saveAll(...$entities);
    }

    /**
     * Löscht eine Entity
     */
    public function delete(object $entity): void
    {
        $this->entityManager->delete($entity);
    }

    /**
     * Führt eine Funktion in einer Transaktion aus
     */
    public function transaction(callable $callback): mixed
    {
        return $this->entityManager->transaction($callback);
    }
}
