<?php

declare(strict_types=1);

namespace App\Framework\Database\Migration;

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

final readonly class ApplyMigrations
{
    public function __construct(
        private MigrationRunner $runner,
        private MigrationLoader $loader
    ) {
    }

    #[ConsoleCommand('db:migrate', 'Apply all pending migrations')]
    public function migrate(ConsoleInput $input): ExitCode
    {
        echo "Running migrations...\n";

        $skipPreflightChecks = $input->hasOption('skip-preflight') || $input->hasOption('force');

        try {
            // Use the injected loader that leverages the discovery system
            $migrations = $this->loader->loadMigrations();

            $executed = $this->runner->migrate($migrations, $skipPreflightChecks);

            if (empty($executed)) {
                echo "No migrations to run.\n";
            } else {
                echo sprintf("Executed %d migrations.\n", count($executed));
            }

            return ExitCode::SUCCESS;
        } catch (\Throwable $e) {
            echo "❌ Migration failed: " . $e->getMessage() . "\n";
            echo "Error details: " . get_class($e) . "\n";
            echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
            echo "Stack trace:\n" . $e->getTraceAsString() . "\n";

            return ExitCode::SOFTWARE_ERROR;
        }
    }

    #[ConsoleCommand('db:rollback', 'Rollback the last migration batch (only SafelyReversible migrations)')]
    public function rollback(int $steps = 1): ExitCode
    {
        echo "🔄 Rolling back migrations...\n";
        echo "⚠️  Safety Check: Only migrations implementing SafelyReversible will be rolled back.\n\n";

        try {
            // Use the injected loader that leverages the discovery system
            $migrations = $this->loader->loadMigrations();

            $rolledBack = $this->runner->rollback($migrations, $steps);

            if (empty($rolledBack)) {
                echo "✅ No migrations to roll back.\n";
            } else {
                echo sprintf("✅ Successfully rolled back %d migration(s).\n", count($rolledBack));

                foreach ($rolledBack as $migration) {
                    echo "   - {$migration->getDescription()}\n";
                }
            }

            return ExitCode::SUCCESS;
        } catch (\Throwable $e) {
            echo "❌ Rollback failed: " . $e->getMessage() . "\n\n";

            // Check if it's a non-reversible migration error
            if (str_contains($e->getMessage(), 'does not support safe rollback')) {
                echo "ℹ️  This migration cannot be safely rolled back.\n";
                echo "   Reason: Data loss would occur during rollback.\n\n";
                echo "💡 Recommendation:\n";
                echo "   Create a new forward migration to undo the changes instead:\n";
                echo "   php console.php make:migration FixYourChanges\n\n";
                echo "📖 See docs/claude/examples/migrations/SafeVsUnsafeMigrations.md for guidelines.\n";
            } else {
                echo "Error details: " . get_class($e) . "\n";
                echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
            }

            return ExitCode::SOFTWARE_ERROR;
        }
    }

    #[ConsoleCommand('db:status', 'Show migration status')]
    public function status(): ExitCode
    {
        echo "Migration Status:\n";
        echo str_repeat('-', 80) . "\n";

        // Use the injected loader that leverages the discovery system
        $migrations = $this->loader->loadMigrations();
        $statusCollection = $this->runner->getStatus($migrations);

        foreach ($statusCollection as $migrationStatus) {
            echo sprintf(
                "  %s %s - %s\n",
                $migrationStatus->getStatusIcon(),
                $migrationStatus->version,
                $migrationStatus->description
            );
        }

        echo "\n";

        return ExitCode::SUCCESS;
    }
}
