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


declare(strict_types=1);
namespace BookiFlex\Extensions\Payment\Infrastructure\Payum;

use Payum\Core\Exception\InvalidArgumentException;
use Payum\Core\Registry\SimpleRegistry;

defined( 'ABSPATH' ) || exit;

/**
 * Custom registry class that extends SimpleRegistry to handle storage retrieval.
 *
 * This class overrides the getStorage method to provide a custom implementation
 * for retrieving storage based on the Cycle ORM Proxy class.
 */
class CustomRegistry extends SimpleRegistry
{
    public function getStorage($class)
    {
        $class = is_object($class) ? get_class($class) : $class;

        // TODO: this is a quick fix. I have to find a better\clean solution.
        if (class_exists($class)) {
            if (interface_exists('Doctrine\Persistence\Proxy')) {
                $rc = new \ReflectionClass($class);
                if ($rc->implementsInterface(\Doctrine\Persistence\Proxy::class)) {
                    $class = $rc->getParentClass()->getName();
                }
            } elseif (interface_exists('Doctrine\Common\Persistence\Proxy')) {
                $rc = new \ReflectionClass($class);
                if ($rc->implementsInterface(\Doctrine\Common\Persistence\Proxy::class)) {
                    $class = $rc->getParentClass()->getName();
                }
            } elseif (interface_exists('Cycle\ORM\EntityProxyInterface')) {
                $rc = new \ReflectionClass($class);
                if ($rc->implementsInterface(\Cycle\ORM\EntityProxyInterface::class)) {
                    $class = $rc->getParentClass()->getName();
                }
            }
        }

        if (!isset($this->storages[$class])) {
            throw new InvalidArgumentException(sprintf(
                'A storage for model %s was not registered. There are storages for next models: %s.',
                $class,
                implode(', ', array_keys($this->storages))
            ));
        }

        return $this->getService($this->storages[$class]);
    }
}
