<?php

declare(strict_types=1);

namespace app\vendor\apexl\io\src\Io\modules\system\commands;

use apexl\Config\Configuration;
use RecursiveArrayIterator;
use RecursiveIteratorIterator;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'config:dump', description: 'Dumps config file to console')]
class DumpConfigCommand extends Command
{

    protected function configure(): void
    {
        parent::configure();

        $this->addArgument('key', InputArgument::OPTIONAL);
        $this->addOption('output', 'o', InputArgument::OPTIONAL, 'Output format (json, php)', 'table');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $config = Configuration::getInstance();

        $key = $input->getArgument('key');

        $data = $key ? ($config->{$key} ?? null) : $config->getData();

        $data = $this->toFlatArray((array) $data);

        $outputDisplay = $input->getOption('output');

        if ($outputDisplay === 'table') {
            $table = new Table($output);
            $table
                ->setHeaderTitle($key ?? 'Config')
                ->setHeaders(['Key', 'Value'])
                ->setRows(
                    array_map(
                        fn(string $value, string $key): array => [$key, $value],
                        $data,
                        array_keys($data)
                    )
                );
            $table->render();
        } else {
            $config = match ($input->getOption('output')) {
                'json' => json_encode($data, JSON_PRETTY_PRINT),
                default => print_r($data, true),
            };

            $output->write($config);
        }


        return Command::SUCCESS;
    }

    private function toFlatArray(array $data): array
    {
        $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
        $result = [];
        foreach ($iterator as $leafValue) {
            $keys = [];
            foreach (range(0, $iterator->getDepth()) as $depth) {
                $keys[] = $iterator->getSubIterator($depth)->key();
            }
            $result[join('.', $keys)] = $leafValue;
        }

        return $result;
    }
}
