<?php
declare(strict_types=1);

namespace App\Framework\Console;

namespace App\Framework\Console;

use App\Framework\Console\Components\InteractiveMenu;

final class ConsoleInput implements ConsoleInputInterface
{
    private array $arguments;
    private array $options = [];
    private ?ConsoleOutputInterface $output = null;

    public function __construct(array $arguments, ?ConsoleOutputInterface $output = null)
    {
        $this->parseArguments($arguments);
        $this->output = $output ?? new ConsoleOutput();
    }

    private function parseArguments(array $arguments): void
    {
        $this->arguments = [];

        foreach ($arguments as $arg) {
            if (str_starts_with($arg, '--')) {
                // Long option: --key=value oder --key
                $parts = explode('=', substr($arg, 2), 2);
                $this->options[$parts[0]] = $parts[1] ?? true;
            } elseif (str_starts_with($arg, '-')) {
                // Short option: -k value oder -k
                $key = substr($arg, 1);
                $this->options[$key] = true;
            } else {
                // Argument
                $this->arguments[] = $arg;
            }
        }
    }

    public function getArgument(int $index, ?string $default = null): ?string
    {
        return $this->arguments[$index] ?? $default;
    }

    public function getArguments(): array
    {
        return $this->arguments;
    }

    public function getOption(string $name, mixed $default = null): mixed
    {
        return $this->options[$name] ?? $default;
    }

    public function hasOption(string $name): bool
    {
        return isset($this->options[$name]);
    }

    public function getOptions(): array
    {
        return $this->options;
    }

    /**
     * Fragt nach einer Benutzereingabe.
     */
    public function ask(string $question, string $default = ''): string
    {
        return $this->output->askQuestion($question, $default);
    }

    /**
     * Fragt nach einem Passwort (versteckte Eingabe).
     */
    public function askPassword(string $question): string
    {
        echo $question . ": ";

        // Verstecke Eingabe
        system('stty -echo');
        $password = trim(fgets(STDIN));
        system('stty echo');
        echo PHP_EOL;

        return $password;
    }

    /**
     * Fragt nach einer Bestätigung (Ja/Nein).
     */
    public function confirm(string $question, bool $default = false): bool
    {
        return $this->output->confirm($question, $default);
    }

    /**
     * Zeigt ein einfaches Auswahlmenü.
     */
    public function choice(string $question, array $choices, mixed $default = null): mixed
    {
        $menu = new InteractiveMenu($this->output);
        $menu->setTitle($question);

        foreach ($choices as $key => $choice) {
            $menu->addItem($choice, null, $key);
        }

        return $menu->showSimple();
    }

    /**
     * Zeigt ein interaktives Menü mit Pfeiltasten-Navigation.
     */
    public function menu(string $title, array $items): mixed
    {
        $menu = new InteractiveMenu($this->output);
        $menu->setTitle($title);

        foreach ($items as $key => $item) {
            if ($item === '---') {
                $menu->addSeparator();
            } else {
                $menu->addItem($item, null, $key);
            }
        }

        return $menu->showInteractive();
    }

    /**
     * Ermöglicht die Mehrfachauswahl aus einer Liste von Optionen.
     */
    public function multiSelect(string $question, array $options): array
    {
        $this->output->writeLine($question, ConsoleColor::BRIGHT_CYAN);
        $this->output->writeLine("Mehrfachauswahl mit Komma getrennt (z.B. 1,3,5):");

        foreach ($options as $key => $option) {
            $this->output->writeLine("  " . ($key + 1) . ": {$option}");
        }

        $this->output->write("Ihre Auswahl: ", ConsoleColor::BRIGHT_CYAN);
        $input = trim(fgets(STDIN));

        $selected = [];
        $indices = explode(',', $input);

        foreach ($indices as $index) {
            $index = (int)trim($index) - 1;
            if (isset($options[$index])) {
                $selected[] = $options[$index];
            }
        }

        return $selected;
    }
}
