<?php

declare(strict_types=1);

namespace App\Framework\Console\Examples;

use App\Framework\Console\ConsoleCommand;
use App\Framework\Console\ConsoleInput;
use App\Framework\Console\ConsoleOutputInterface;
use App\Framework\Console\ExitCode;

/**
 * Demo command showing flexible parameter support
 *
 * This command demonstrates that ConsoleInput and ConsoleOutput
 * parameters are now optional and can be mixed with other parameters
 */
final readonly class FlexibleParameterDemoCommand
{
    /**
     * Command without any parameters
     */
    #[ConsoleCommand(
        name: 'demo:no-params',
        description: 'Demo command without any parameters'
    )]
    public function withoutParameters(): ExitCode
    {
        echo "This command has no parameters!\n";

        return ExitCode::SUCCESS;
    }

    /**
     * Command with only user parameters (no framework types)
     */
    #[ConsoleCommand(
        name: 'demo:user-params',
        description: 'Demo command with only user parameters'
    )]
    public function withUserParameters(string $name, int $age = 18): ExitCode
    {
        echo "Name: {$name}\n";
        echo "Age: {$age}\n";

        return ExitCode::SUCCESS;
    }

    /**
     * Command with ConsoleOutput only
     */
    #[ConsoleCommand(
        name: 'demo:with-output',
        description: 'Demo command with ConsoleOutput parameter'
    )]
    public function withOutput(ConsoleOutputInterface $output, string $message = 'Hello World'): ExitCode
    {
        $output->writeLine("Message from ConsoleOutput: {$message}");

        return ExitCode::SUCCESS;
    }

    /**
     * Command with ConsoleInput only
     */
    #[ConsoleCommand(
        name: 'demo:with-input',
        description: 'Demo command with ConsoleInput parameter'
    )]
    public function withInput(ConsoleInput $input): ExitCode
    {
        $args = $input->getArguments();
        echo "Arguments: " . json_encode($args) . "\n";

        return ExitCode::SUCCESS;
    }

    /**
     * Command with both ConsoleInput and ConsoleOutput
     */
    #[ConsoleCommand(
        name: 'demo:with-both',
        description: 'Demo command with both ConsoleInput and ConsoleOutput'
    )]
    public function withBoth(ConsoleInput $input, ConsoleOutputInterface $output): ExitCode
    {
        $output->writeLine("Input arguments: " . json_encode($input->getArguments()));

        return ExitCode::SUCCESS;
    }

    /**
     * Command mixing framework and user parameters (Output first)
     */
    #[ConsoleCommand(
        name: 'demo:mixed-output-first',
        description: 'Demo command with mixed parameters (output first)'
    )]
    public function mixedOutputFirst(
        ConsoleOutputInterface $output,
        string $name,
        int $count = 3
    ): ExitCode {
        $output->writeLine("Name: {$name}");
        $output->writeLine("Count: {$count}");

        return ExitCode::SUCCESS;
    }

    /**
     * Command mixing framework and user parameters (Output in middle)
     */
    #[ConsoleCommand(
        name: 'demo:mixed-output-middle',
        description: 'Demo command with mixed parameters (output in middle)'
    )]
    public function mixedOutputMiddle(
        string $name,
        ConsoleOutputInterface $output,
        int $count = 3
    ): ExitCode {
        $output->writeLine("Name: {$name}");
        $output->writeLine("Count: {$count}");

        return ExitCode::SUCCESS;
    }

    /**
     * Command mixing framework and user parameters (Output last)
     */
    #[ConsoleCommand(
        name: 'demo:mixed-output-last',
        description: 'Demo command with mixed parameters (output last)'
    )]
    public function mixedOutputLast(
        string $name,
        int $count,
        ConsoleOutputInterface $output
    ): ExitCode {
        $output->writeLine("Name: {$name}");
        $output->writeLine("Count: {$count}");

        return ExitCode::SUCCESS;
    }

    /**
     * Command with all types mixed
     */
    #[ConsoleCommand(
        name: 'demo:all-mixed',
        description: 'Demo command with all parameter types mixed'
    )]
    public function allMixed(
        ConsoleInput $input,
        string $operation,
        ConsoleOutputInterface $output,
        int $iterations = 1,
        bool $verbose = false
    ): ExitCode {
        $output->writeLine("Operation: {$operation}");
        $output->writeLine("Iterations: {$iterations}");
        $output->writeLine("Verbose: " . ($verbose ? 'true' : 'false'));

        if ($verbose) {
            $output->writeLine("Raw arguments: " . json_encode($input->getArguments()));
        }

        return ExitCode::SUCCESS;
    }
}
