<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\PrestaShop\Configuration;

use InPost\International\PrestaShop\Shop\ShopConstraintContextInterface;
use PrestaShop\PrestaShop\Core\Domain\Configuration\ShopConfigurationInterface;
use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint;

if (!defined('_PS_VERSION_')) {
    exit;
}

final class ContextAwareConfiguration implements ShopConfigurationInterface
{
    /**
     * @var ShopConfigurationInterface
     */
    private $configuration;

    /**
     * @var ShopConstraintContextInterface
     */
    private $context;

    public function __construct(ShopConfigurationInterface $configuration, ShopConstraintContextInterface $context)
    {
        $this->configuration = $configuration;
        $this->context = $context;
    }

    public function get($key, $default = null, ShopConstraint $shopConstraint = null)
    {
        $shopConstraint = $shopConstraint ?? $this->context->getShopConstraint();

        return $this->configuration->get($key, $default, $shopConstraint);
    }

    public function set($key, $value, ShopConstraint $shopConstraint = null): ShopConfigurationInterface
    {
        $shopConstraint = $shopConstraint ?? $this->context->getShopConstraint();
        $this->configuration->set($key, $value, $shopConstraint);

        return $this;
    }

    public function has($key, ShopConstraint $shopConstraint = null): bool
    {
        $shopConstraint = $shopConstraint ?? $this->context->getShopConstraint();

        return (bool) $this->configuration->has($key, $shopConstraint);
    }

    public function remove($key): ShopConfigurationInterface
    {
        $this->configuration->remove($key);

        return $this;
    }

    public function keys(): array
    {
        return $this->configuration->keys();
    }

    public function getInt($key, $default = 0, ShopConstraint $shopConstraint = null): int
    {
        $shopConstraint = $shopConstraint ?? $this->context->getShopConstraint();

        if (is_callable([$this->configuration, 'getInt'])) {
            return $this->configuration->getInt($key, $default, $shopConstraint);
        }

        return (int) $this->get($key, $default, $shopConstraint);
    }

    public function getBoolean($key, $default = false, ShopConstraint $shopConstraint = null): bool
    {
        $shopConstraint = $shopConstraint ?? $this->context->getShopConstraint();

        if (is_callable([$this->configuration, 'getBoolean'])) {
            return $this->configuration->getBoolean($key, $default, $shopConstraint);
        }

        return (bool) $this->get($key, $default, $shopConstraint);
    }

    /**
     * Forwards calls to the inner configuration.
     *
     * @return mixed
     */
    public function __call(string $name, array $arguments)
    {
        return $this->configuration->$name(...$arguments);
    }
}
