<?php

declare(strict_types=1);

namespace App\Framework\Deployment\Ssl\Commands;

use App\Framework\Config\Environment;
use App\Framework\Console\Attributes\ConsoleCommand;
use App\Framework\Console\ConsoleOutput;
use App\Framework\Console\ExitCode;
use App\Framework\Deployment\Ssl\Services\SslCertificateService;
use App\Framework\Deployment\Ssl\ValueObjects\SslConfiguration;

/**
 * Console command to renew SSL certificates
 */
#[ConsoleCommand(
    name: 'ssl:renew',
    description: 'Renew Let\'s Encrypt SSL certificates'
)]
final readonly class SslRenewCommand
{
    public function __construct(
        private SslCertificateService $sslService,
        private Environment $environment,
        private ConsoleOutput $output
    ) {}

    public function execute(?bool $force = null): ExitCode
    {
        $this->output->writeLine('🔄 Renewing SSL Certificates...');
        $this->output->writeLine('');

        try {
            // Load configuration from environment
            $config = SslConfiguration::fromEnvironment($this->environment);

            $this->output->writeLine('Domain: ' . $config->domain->value);
            $this->output->writeLine('');

            // Check current status
            $this->output->write('Checking current certificate status... ');
            $currentStatus = $this->sslService->getStatus(
                $config->domain,
                $config->certbotConfDir->toString()
            );

            if (!$currentStatus->exists) {
                $this->output->writeLine('❌ Not found');
                $this->output->writeLine('');
                $this->output->writeLine('No certificate exists for this domain.');
                $this->output->writeLine('Run "ssl:init" to obtain a new certificate first.');
                return ExitCode::FAILURE;
            }

            $this->output->writeLine('✅ Found');
            $this->output->writeLine('');

            // Display current status
            $this->output->writeLine('Current Status:');
            $this->output->writeLine('  Valid Until: ' . $currentStatus->notAfter?->format('Y-m-d H:i:s'));
            $this->output->writeLine('  Days Until Expiry: ' . $currentStatus->daysUntilExpiry);
            $this->output->writeLine('  Health: ' . $currentStatus->getHealthStatus());
            $this->output->writeLine('');

            // Check if renewal is needed
            if (!$currentStatus->needsRenewal() && $force !== true) {
                $this->output->writeLine('ℹ️  Certificate does not need renewal yet.');
                $this->output->writeLine('   Certificates are automatically renewed 30 days before expiry.');
                $this->output->writeLine('');
                $this->output->writeLine('Use --force flag to force renewal anyway.');
                return ExitCode::SUCCESS;
            }

            if ($force === true && !$currentStatus->needsRenewal()) {
                $this->output->writeLine('⚠️  Forcing renewal even though certificate is still valid...');
                $this->output->writeLine('');
            }

            // Renew certificate
            $this->output->writeLine('Renewing certificate...');
            $status = $this->sslService->renew($config);

            $this->output->writeLine('');
            $this->output->writeLine('✅ Certificate renewed successfully!');
            $this->output->writeLine('');

            // Display new status
            $this->output->writeLine('New Certificate Information:');
            $this->output->writeLine('  Valid Until: ' . $status->notAfter?->format('Y-m-d H:i:s'));
            $this->output->writeLine('  Days Until Expiry: ' . $status->daysUntilExpiry);
            $this->output->writeLine('  Health: ' . $status->getHealthStatus());
            $this->output->writeLine('');

            $this->output->writeLine('Next step: Reload/restart your web server to use the new certificate');

            return ExitCode::SUCCESS;

        } catch (\Exception $e) {
            $this->output->writeLine('');
            $this->output->writeLine('❌ Error: ' . $e->getMessage());
            $this->output->writeLine('');
            return ExitCode::FAILURE;
        }
    }
}
