<?php

declare(strict_types=1);

namespace App\Framework\Process\Console;

use App\Framework\Console\Attribute\ConsoleCommand;
use App\Framework\Console\ConsoleInput;
use App\Framework\Console\ExitCode;
use App\Framework\Process\Services\DockerService;

/**
 * Docker Console Commands.
 */
final readonly class DockerCommands
{
    public function __construct(
        private DockerService $dockerService
    ) {
    }

    #[ConsoleCommand(name: 'docker:list', description: 'List Docker containers')]
    public function list(ConsoleInput $input): int
    {
        $all = $input->hasOption('all') || $input->hasOption('a');

        echo "Loading Docker containers" . ($all ? ' (including stopped)' : '') . "...\n\n";

        $containers = $this->dockerService->listContainers($all);

        if (empty($containers)) {
            echo "No containers found.\n";

            return ExitCode::SUCCESS;
        }

        echo "🐳 Docker Containers (" . count($containers) . "):\n\n";

        foreach ($containers as $container) {
            $statusIcon = $container->isRunning ? '✅' : '⏸️';
            echo "  {$statusIcon} {$container->name} ({$container->id})\n";
            echo "     Image:  {$container->image}\n";
            echo "     Status: {$container->status}\n";
            echo "\n";
        }

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand(name: 'docker:stats', description: 'Show container statistics')]
    public function stats(ConsoleInput $input): int
    {
        $containerId = $input->getArgument('container');

        if ($containerId === null) {
            echo "❌ Please provide a container ID or name.\n";
            echo "Usage: php console.php docker:stats <container>\n";

            return ExitCode::FAILURE;
        }

        echo "Loading stats for container: {$containerId}...\n\n";

        $stats = $this->dockerService->getContainerStats($containerId);

        if ($stats === null) {
            echo "❌ Could not retrieve stats for container: {$containerId}\n";

            return ExitCode::FAILURE;
        }

        echo "📊 Container Statistics:\n\n";
        echo "  Container: {$stats->containerName}\n";
        echo "  ID:        {$stats->containerId}\n\n";

        echo "  CPU Usage:    {$stats->cpuPercent->format(2)}\n";
        echo "  Memory:       {$stats->memoryUsage->toHumanReadable()} / {$stats->memoryLimit->toHumanReadable()} ({$stats->memoryPercent->format(2)})\n";
        echo "  Network I/O:  ↓ {$stats->networkIn->toHumanReadable()} / ↑ {$stats->networkOut->toHumanReadable()}\n";
        echo "  Block I/O:    ↓ {$stats->blockIn->toHumanReadable()} / ↑ {$stats->blockOut->toHumanReadable()}\n";

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand(name: 'docker:logs', description: 'Show container logs')]
    public function logs(ConsoleInput $input): int
    {
        $containerId = $input->getArgument('container');

        if ($containerId === null) {
            echo "❌ Please provide a container ID or name.\n";
            echo "Usage: php console.php docker:logs <container> [--lines=N]\n";

            return ExitCode::FAILURE;
        }

        $lines = (int) ($input->getOption('lines') ?? 100);

        echo "Loading logs for container: {$containerId} (last {$lines} lines)...\n\n";

        $logs = $this->dockerService->getContainerLogs($containerId, $lines);

        if ($logs === null) {
            echo "❌ Could not retrieve logs for container: {$containerId}\n";

            return ExitCode::FAILURE;
        }

        echo "--- Container Logs ---\n\n";
        echo $logs;

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand(name: 'docker:inspect', description: 'Inspect container details')]
    public function inspect(ConsoleInput $input): int
    {
        $containerId = $input->getArgument('container');

        if ($containerId === null) {
            echo "❌ Please provide a container ID or name.\n";
            echo "Usage: php console.php docker:inspect <container>\n";

            return ExitCode::FAILURE;
        }

        echo "Inspecting container: {$containerId}...\n\n";

        $data = $this->dockerService->inspectContainer($containerId);

        if ($data === null) {
            echo "❌ Could not inspect container: {$containerId}\n";

            return ExitCode::FAILURE;
        }

        echo "--- Container Inspection ---\n\n";
        echo json_encode($data, JSON_PRETTY_PRINT);
        echo "\n";

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand(name: 'docker:start', description: 'Start a container')]
    public function start(ConsoleInput $input): int
    {
        $containerId = $input->getArgument('container');

        if ($containerId === null) {
            echo "❌ Please provide a container ID or name.\n";
            echo "Usage: php console.php docker:start <container>\n";

            return ExitCode::FAILURE;
        }

        echo "Starting container: {$containerId}...\n";

        $success = $this->dockerService->startContainer($containerId);

        if ($success) {
            echo "✅ Container started successfully!\n";

            return ExitCode::SUCCESS;
        }

        echo "❌ Failed to start container.\n";

        return ExitCode::FAILURE;
    }

    #[ConsoleCommand(name: 'docker:stop', description: 'Stop a container')]
    public function stop(ConsoleInput $input): int
    {
        $containerId = $input->getArgument('container');

        if ($containerId === null) {
            echo "❌ Please provide a container ID or name.\n";
            echo "Usage: php console.php docker:stop <container>\n";

            return ExitCode::FAILURE;
        }

        echo "Stopping container: {$containerId}...\n";

        $success = $this->dockerService->stopContainer($containerId);

        if ($success) {
            echo "✅ Container stopped successfully!\n";

            return ExitCode::SUCCESS;
        }

        echo "❌ Failed to stop container.\n";

        return ExitCode::FAILURE;
    }

    #[ConsoleCommand(name: 'docker:restart', description: 'Restart a container')]
    public function restart(ConsoleInput $input): int
    {
        $containerId = $input->getArgument('container');

        if ($containerId === null) {
            echo "❌ Please provide a container ID or name.\n";
            echo "Usage: php console.php docker:restart <container>\n";

            return ExitCode::FAILURE;
        }

        echo "Restarting container: {$containerId}...\n";

        $success = $this->dockerService->restartContainer($containerId);

        if ($success) {
            echo "✅ Container restarted successfully!\n";

            return ExitCode::SUCCESS;
        }

        echo "❌ Failed to restart container.\n";

        return ExitCode::FAILURE;
    }

    #[ConsoleCommand(name: 'docker:version', description: 'Show Docker version')]
    public function version(ConsoleInput $input): int
    {
        $version = $this->dockerService->getVersion();

        if ($version === null) {
            echo "❌ Could not retrieve Docker version.\n";

            return ExitCode::FAILURE;
        }

        echo "Docker version: {$version}\n";

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand(name: 'docker:status', description: 'Check if Docker is running')]
    public function status(ConsoleInput $input): int
    {
        echo "Checking Docker status...\n\n";

        $isRunning = $this->dockerService->isRunning();

        if ($isRunning) {
            echo "✅ Docker is running!\n";

            $version = $this->dockerService->getVersion();
            if ($version !== null) {
                echo "   Version: {$version}\n";
            }

            return ExitCode::SUCCESS;
        }

        echo "❌ Docker is not running or not accessible.\n";

        return ExitCode::FAILURE;
    }
}
