<?php

declare(strict_types=1);

namespace App\Framework\Deployment\Docker\Commands;

use App\Framework\Console\ConsoleCommand;
use App\Framework\Console\ConsoleInput;
use App\Framework\Console\ExitCode;
use App\Framework\Deployment\Docker\Services\DockerDeploymentService;
use App\Framework\Deployment\Docker\ValueObjects\ContainerId;
use App\Framework\Process\Services\DockerService;

/**
 * Docker Deployment Console Commands
 *
 * Deployment-focused Docker commands for container orchestration
 */
final readonly class DockerDeploymentCommands
{
    public function __construct(
        private DockerDeploymentService $deploymentService,
        private DockerService $dockerService
    ) {
    }

    #[ConsoleCommand(name: 'docker:deploy:restart', description: 'Restart container with health checks and deployment tracking')]
    public function deployRestart(string $container, ?bool $noHealthCheck = null): ExitCode
    {
        $healthCheck = $noHealthCheck !== true;
        $containerId = ContainerId::fromString($container);

        echo "🚀 Starting deployment: Restart container '{$container}'\n";
        if ($healthCheck) {
            echo "   Health checks: ENABLED\n";
        } else {
            echo "   Health checks: DISABLED\n";
        }
        echo "\n";

        $result = $this->deploymentService->restartContainer($containerId, $healthCheck);

        if ($result->isSuccess()) {
            echo "✅ Deployment succeeded!\n";
            echo "   Container:  {$container}\n";
            echo "   Duration:   {$result->duration->toHumanReadable()}\n";
            echo "   Message:    {$result->message}\n";
            return ExitCode::SUCCESS;
        }

        echo "❌ Deployment failed!\n";
        echo "   Container:  {$container}\n";
        echo "   Duration:   {$result->duration->toHumanReadable()}\n";
        echo "   Error:      {$result->error}\n";
        return ExitCode::FAILURE;
    }

    #[ConsoleCommand(name: 'docker:deploy:stop', description: 'Stop container gracefully with timeout')]
    public function deployStop(string $container, int $timeout = 10): ExitCode
    {
        $containerId = ContainerId::fromString($container);

        echo "🛑 Stopping container: {$container}\n";
        echo "   Timeout: {$timeout}s\n\n";

        $success = $this->deploymentService->stopContainer($containerId, $timeout);

        if ($success) {
            echo "✅ Container stopped successfully!\n";
            return ExitCode::SUCCESS;
        }

        echo "❌ Failed to stop container.\n";
        return ExitCode::FAILURE;
    }

    #[ConsoleCommand(name: 'docker:deploy:start', description: 'Start container with health check')]
    public function deployStart(string $container, ?bool $noHealthCheck = null): ExitCode
    {
        $healthCheck = $noHealthCheck !== true;
        $containerId = ContainerId::fromString($container);

        echo "▶️  Starting container: {$container}\n";
        if ($healthCheck) {
            echo "   Health checks: ENABLED\n";
        }
        echo "\n";

        $success = $this->deploymentService->startContainer($containerId, $healthCheck);

        if ($success) {
            echo "✅ Container started successfully!\n";
            if ($healthCheck) {
                echo "   Health check: PASSED\n";
            }
            return ExitCode::SUCCESS;
        }

        echo "❌ Failed to start container";
        if ($healthCheck) {
            echo " or health check failed";
        }
        echo ".\n";
        return ExitCode::FAILURE;
    }

    #[ConsoleCommand(name: 'docker:deploy:logs', description: 'Get container logs for deployment debugging')]
    public function deployLogs(string $container, int $lines = 100): ExitCode
    {
        $containerId = ContainerId::fromString($container);

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

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

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

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

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand(name: 'docker:deploy:status', description: 'Show deployment status of containers')]
    public function deployStatus(): ExitCode
    {
        echo "📊 Docker Deployment Status\n\n";

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

        if (empty($containers)) {
            echo "No containers found.\n";
            return ExitCode::SUCCESS;
        }

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

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

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand(name: 'docker:deploy:exec', description: 'Execute command in container for deployment tasks')]
    public function deployExec(ConsoleInput $input): ExitCode
    {
        $containerName = $input->getArgument('container');
        $command = $input->getArgument('command');

        if ($containerName === null || $command === null) {
            echo "❌ Please provide container and command.\n";
            echo "Usage: php console.php docker:deploy:exec <container> <command>\n";
            echo "Example: php console.php docker:deploy:exec php composer dump-autoload\n";
            return ExitCode::FAILURE;
        }

        // Parse command (remaining arguments)
        $args = [$command];
        $i = 2;
        while (($arg = $input->getArgument((string) $i)) !== null) {
            $args[] = $arg;
            $i++;
        }

        $containerId = ContainerId::fromString($containerName);

        echo "⚙️  Executing in container '{$containerName}':\n";
        echo "   Command: " . implode(' ', $args) . "\n\n";

        $output = $this->deploymentService->execInContainer($containerId, $args);

        if ($output === null) {
            echo "❌ Failed to execute command in container.\n";
            return ExitCode::FAILURE;
        }

        echo "--- Command Output ---\n\n";
        echo $output;
        echo "\n✅ Command executed successfully!\n";

        return ExitCode::SUCCESS;
    }
}
