<?php

declare(strict_types=1);

namespace App\Framework\Database\Services;

use App\Framework\Database\DatabaseManager;
use App\Framework\Database\HydratorInterface;
use App\Framework\Database\IdentityMap;
use App\Framework\Database\QueryBuilder\QueryBuilderFactory;
use App\Framework\Database\QueryBuilder\SelectQueryBuilder;

final readonly class EntityQueryManager
{
    public function __construct(
        private DatabaseManager $databaseManager,
        private QueryBuilderFactory $queryBuilderFactory,
        private IdentityMap $identityMap,
        private HydratorInterface $hydrator
    ) {
    }

    /**
     * Create a new query builder
     */
    public function createQueryBuilder(): SelectQueryBuilder
    {
        return $this->queryBuilderFactory->select();
    }

    /**
     * Create a query builder for a specific entity
     */
    public function createQueryBuilderFor(string $entityClass): SelectQueryBuilder
    {
        return $this->queryBuilderFactory->selectFromWithEntity($entityClass, $this->identityMap, $this->hydrator);
    }

    /**
     * Create a query builder for a table
     */
    public function createQueryBuilderForTable(string $tableName): SelectQueryBuilder
    {
        return $this->queryBuilderFactory->selectFromTable($tableName);
    }

    /**
     * Führt eine Funktion in einer Transaktion aus
     */
    public function transaction(callable $callback): mixed
    {
        $connection = $this->databaseManager->getConnection();

        // Wenn bereits in einer Transaktion, führe Callback direkt aus
        if ($connection->inTransaction()) {
            return $callback();
        }

        // Neue Transaktion starten
        $connection->beginTransaction();

        try {
            $result = $callback();
            $connection->commit();

            return $result;
        } catch (\Throwable $e) {
            $connection->rollback();

            throw $e;
        }
    }
}
