<?php declare(strict_types=1);

namespace Newland\Toubiz\Sync\Neos\Command\Helper;

use Neos\Flow\Cli\ConsoleOutput;
use Neos\Flow\Configuration\Exception\InvalidConfigurationException;
use Newland\Toubiz\Api\Constants\Language;
use Neos\Flow\Annotations as Flow;

/**
 * @Flow\Scope("singleton")
 */
class ConfigurationHelper
{
    public const CLIENT_DEFAULT = 'default';

    /**
     * @var array
     * @Flow\InjectConfiguration()
     */
    protected $configuration;

    /**
     * @var ConsoleOutput
     * @Flow\Inject()
     */
    protected $output;

    /**
     * @var array
     */
    protected $defaults = [];

    public function setDefaults(array $defaults): void
    {
        $this->defaults = $defaults;
    }

    public function mergeWithDefaults(array $configuration): array
    {
        return (array) array_replace_recursive($this->defaults, $configuration);
    }

    public function getConfigurationForService(string $service): ?array
    {
        $configuration = $this->configuration['services'][$service] ?? null;

        if ($configuration === null) {
            return null;
        }

        if (!array_key_exists('clients', $configuration)) {
            $configuration = $this->wrapConfigurationInDefaultClient($configuration, $service);
        }

        $configuration['languages'] = $configuration['languages'] ?? [ Language::DE ];
        return array_replace_recursive($this->defaults, $configuration);
    }

    public function getDefaultClient(string $service): string
    {
        $configuration = $this->getConfigurationForService($service);

        if ($configuration === null) {
            throw new InvalidConfigurationException(sprintf('Service %s is not configured.', $service));
        }

        $firstClient = array_keys($configuration['clients'])[0];

        $defaultClientConfig = $configuration['clients']['default']
            ?? $configuration['clients']['Default']
            ?? $configuration['clients'][$firstClient];

        return $defaultClientConfig['client'] ?? $firstClient;
    }

    /**
     * @param array $configuration
     * @param string $service
     * @return array
     * @deprecated
     */
    private function wrapConfigurationInDefaultClient(array $configuration, string $service): array
    {
        $this->output->outputLine(
            sprintf(
                '<i>Deprecated configuration detected. Please move you configuration from `%s` to `%s`.',
                sprintf('Newland.Toubiz.Sync.Neos.services.Toubiz/services.%s.[SERVICE_CONFIG]', $service),
                sprintf('Newland.Toubiz.Sync.Neos.services.Toubiz/services.%s.clients.*.[SERVICE_CONFIG]', $service)
            )
        );

        return [ 'clients' => [ static::CLIENT_DEFAULT => $configuration ] ];
    }
}
