<?php
/**
 * BookiFlex Core
 *
 * @package    BookiFlex
 * @subpackage Core
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */


declare(strict_types=1);
namespace BookiFlex\Core\ORM;

use BookiFlex\Core\Contract\DeferrerEvent\DeferredEventSupportInterface;
use BookiFlex\Core\Contract\DeferrerEvent\EventsReleaser;
use Cycle\ORM\EntityManagerInterface;
use Cycle\ORM\Transaction\StateInterface;

defined( 'ABSPATH' ) || exit;

class EntityManagerDecorator implements EntityManagerInterface
{
    private array $persistedEntities = [];

    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private readonly EventsReleaser $eventsReleaser
    ) {
    }

    public function persistState(object $entity, bool $cascade = true): static
    {
        $this->entityManager->persistState($entity, $cascade);
        $this->persistEntity($entity);

        return $this;
    }

    public function persist(object $entity, bool $cascade = true): static
    {
        $this->entityManager->persist($entity, $cascade);
        $this->persistEntity($entity);

        return $this;
    }

    public function delete(object $entity, bool $cascade = true): static
    {
        $this->entityManager->delete($entity, $cascade);
        $this->persistEntity($entity);

        return $this;
    }

    public function run(): StateInterface
    {
        $state = $this->entityManager->run();
        if ($state->isSuccess() && !empty($this->persistedEntities)) {
            $persistedEntities       = $this->persistedEntities;
            $this->persistedEntities = [];
            $this->eventsReleaser->releaseEvents($persistedEntities);
        }

        return $state;
    }

    public function clean(): static
    {
        $this->entityManager->clean();

        return $this;
    }

    public function getPersistedEntities(): array
    {
        return $this->persistedEntities;
    }

    private function persistEntity(object $entity): void
    {
        if ($entity instanceof DeferredEventSupportInterface) {
            $this->persistedEntities[] = $entity;
        }
    }
}
