<?php

declare(strict_types=1);

namespace App\Framework\Console\Commands;

use App\Framework\Console\CommandGroup;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleCommand;
use App\Framework\Console\ConsoleInput;
use App\Framework\Console\ConsoleOutputInterface;
use App\Framework\Console\ExitCode;
use App\Framework\Console\Progress\LongRunning;
use App\Framework\Console\Progress\ProgressAwareOutput;
use App\Framework\Console\Progress\ProgressType;

#[CommandGroup(
    name: 'Demo',
    description: 'Demonstration commands for framework features',
    icon: '🎯',
    priority: 100
)]
final readonly class ProgressDemoCommand
{
    #[ConsoleCommand('demo:progress', 'Demonstrate progress tracking features')]
    public function demoProgress(ConsoleInput $input, ConsoleOutputInterface $output): ExitCode
    {
        $progressOutput = new ProgressAwareOutput($output);

        $output->writeLine("🎯 Progress Tracking Demonstration", ConsoleColor::BRIGHT_CYAN);
        $output->newLine();

        // Demo 1: Basic Progress Tracker
        $output->writeLine("1. Basic Progress Tracker:", ConsoleColor::BRIGHT_YELLOW);
        $this->demoProgressTracker($progressOutput);
        $output->newLine();

        // Demo 2: Spinner Progress
        $output->writeLine("2. Spinner Progress (indeterminate):", ConsoleColor::BRIGHT_YELLOW);
        $this->demoSpinnerProgress($progressOutput);
        $output->newLine();

        // Demo 3: Progress Bar
        $output->writeLine("3. Simple Progress Bar:", ConsoleColor::BRIGHT_YELLOW);
        $this->demoProgressBar($progressOutput);
        $output->newLine();

        // Demo 4: Nested Progress
        $output->writeLine("4. Nested Progress Operations:", ConsoleColor::BRIGHT_YELLOW);
        $this->demoNestedProgress($progressOutput);

        $output->writeLine("✅ All progress demos completed!", ConsoleColor::GREEN);

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand('demo:migration', 'Simulate database migration with progress')]
    public function demoMigration(ConsoleInput $input, ConsoleOutputInterface $output): ExitCode
    {
        $progressOutput = new ProgressAwareOutput($output);

        $output->writeLine("📦 Simulating Database Migration", ConsoleColor::BRIGHT_CYAN);
        $output->newLine();

        $migrationFiles = [
            '2024_01_01_create_users_table.php',
            '2024_01_02_create_posts_table.php',
            '2024_01_03_add_user_indexes.php',
            '2024_01_04_create_comments_table.php',
            '2024_01_05_add_foreign_keys.php',
        ];

        return $progressOutput->withProgress(
            count($migrationFiles),
            'Running Migrations',
            function ($progress) use ($migrationFiles) {
                foreach ($migrationFiles as $i => $file) {
                    $progress->setTask("Processing {$file}");

                    // Simulate migration steps
                    usleep(500000); // 0.5 seconds
                    $progress->advance(1);
                }

                return ExitCode::SUCCESS;
            }
        );
    }

    #[ConsoleCommand('demo:backup', 'Simulate backup process with progress')]
    public function demoBackup(ConsoleInput $input, ConsoleOutputInterface $output): ExitCode
    {
        $progressOutput = new ProgressAwareOutput($output);

        $output->writeLine("💾 Simulating Database Backup", ConsoleColor::BRIGHT_CYAN);
        $output->newLine();

        return $progressOutput->withSpinner(
            'Creating Backup',
            function ($spinner) {
                $tasks = [
                    'Connecting to database',
                    'Analyzing tables',
                    'Exporting users table',
                    'Exporting posts table',
                    'Exporting comments table',
                    'Compressing backup file',
                    'Verifying backup integrity',
                ];

                foreach ($tasks as $task) {
                    $spinner->setTask($task);
                    usleep(800000); // 0.8 seconds
                    $spinner->advance();
                }

                $spinner->finish('Backup completed successfully');

                return ExitCode::SUCCESS;
            }
        );
    }

    private function demoProgressTracker(ProgressAwareOutput $output): void
    {
        $progress = $output->createProgress(10, 'Processing Items');

        for ($i = 1; $i <= 10; $i++) {
            usleep(200000); // 0.2 seconds
            $progress->advance(1, "Processing item {$i}");
        }

        $progress->finish('All items processed');
    }

    private function demoSpinnerProgress(ProgressAwareOutput $output): void
    {
        $spinner = $output->createSpinner('Analyzing Data');

        $tasks = ['Loading', 'Analyzing', 'Computing', 'Finalizing'];

        foreach ($tasks as $task) {
            $spinner->setTask($task);
            usleep(600000); // 0.6 seconds
            $spinner->advance();
        }

        $spinner->finish('Analysis complete');
    }

    private function demoProgressBar(ProgressAwareOutput $output): void
    {
        $bar = $output->createProgressBar(40);

        for ($i = 0; $i <= 100; $i += 10) {
            $bar->render($i / 100, "Step {$i}%");
            usleep(150000); // 0.15 seconds
        }

        $bar->finish('Simple progress complete');
    }

    private function demoNestedProgress(ProgressAwareOutput $output): void
    {
        $mainProgress = $output->createProgress(3, 'Main Operation');

        // Phase 1
        $mainProgress->setTask('Phase 1: Initialization');
        $subProgress = $output->createProgress(5, 'Initializing');
        for ($i = 1; $i <= 5; $i++) {
            $subProgress->advance(1, "Init step {$i}");
            usleep(100000);
        }
        $subProgress->finish();
        $mainProgress->advance(1);

        $output->newLine();

        // Phase 2
        $mainProgress->setTask('Phase 2: Processing');
        $subProgress = $output->createProgress(8, 'Processing');
        for ($i = 1; $i <= 8; $i++) {
            $subProgress->advance(1, "Process step {$i}");
            usleep(100000);
        }
        $subProgress->finish();
        $mainProgress->advance(1);

        $output->newLine();

        // Phase 3
        $mainProgress->setTask('Phase 3: Cleanup');
        $subProgress = $output->createProgress(3, 'Cleaning Up');
        for ($i = 1; $i <= 3; $i++) {
            $subProgress->advance(1, "Cleanup step {$i}");
            usleep(100000);
        }
        $subProgress->finish();
        $mainProgress->advance(1);

        $mainProgress->finish('Nested operation complete');
    }

    #[ConsoleCommand('demo:auto-progress', 'Demonstrate automatic progress detection')]
    #[LongRunning(estimatedSteps: 15, progressType: ProgressType::TRACKER, title: 'Auto Progress Demo')]
    public function demoAutoProgress(ConsoleInput $input, ConsoleOutputInterface $output): ExitCode
    {
        // This command will automatically get progress tracking via ProgressMiddleware
        // The middleware detects the LongRunning attribute and sets up progress

        $output->writeLine("🤖 Automatic Progress Detection Demo", ConsoleColor::BRIGHT_CYAN);
        $output->writeLine("This command uses the #[LongRunning] attribute for automatic progress", ConsoleColor::GRAY);
        $output->newLine();

        // Simulate a long-running operation
        $steps = [
            'Initializing system',
            'Loading configuration',
            'Connecting to database',
            'Reading user data',
            'Processing records batch 1',
            'Processing records batch 2',
            'Processing records batch 3',
            'Validating data integrity',
            'Generating reports',
            'Optimizing indexes',
            'Creating backups',
            'Sending notifications',
            'Cleaning temporary files',
            'Updating statistics',
            'Finalizing operation',
        ];

        // Get progress from ProgressAwareOutput if available
        if ($output instanceof ProgressAwareOutput) {
            $progress = $output->getCurrentProgress();

            if ($progress) {
                foreach ($steps as $i => $step) {
                    $progress->advance(1, $step);
                    usleep(300000); // 0.3 seconds per step
                }
                $progress->finish('Auto progress demo completed');
            } else {
                $output->writeLine("No automatic progress detected, running without progress...", ConsoleColor::YELLOW);
                foreach ($steps as $step) {
                    $output->writeLine("• $step", ConsoleColor::GRAY);
                    usleep(300000);
                }
            }
        } else {
            $output->writeLine("Standard output - no progress tracking available", ConsoleColor::YELLOW);
        }

        $output->writeLine("✅ Auto progress demo completed!", ConsoleColor::GREEN);

        return ExitCode::SUCCESS;
    }

    #[ConsoleCommand('demo:spinner-auto', 'Demonstrate automatic spinner progress')]
    #[LongRunning(progressType: ProgressType::SPINNER, title: 'Processing Data')]
    public function demoSpinnerAuto(ConsoleInput $input, ConsoleOutputInterface $output): ExitCode
    {
        // This will automatically get a spinner via ProgressMiddleware

        $output->writeLine("🌀 Automatic Spinner Demo", ConsoleColor::BRIGHT_CYAN);
        $output->writeLine("This command uses the #[LongRunning] attribute with SPINNER type", ConsoleColor::GRAY);
        $output->newLine();

        $tasks = [
            'Connecting to API',
            'Fetching data',
            'Processing results',
            'Analyzing patterns',
            'Generating insights',
            'Preparing output',
        ];

        if ($output instanceof ProgressAwareOutput) {
            $spinner = $output->getCurrentProgress();

            if ($spinner) {
                foreach ($tasks as $task) {
                    $spinner->setTask($task);
                    usleep(800000); // 0.8 seconds per task
                    $spinner->advance();
                }
                $spinner->finish('Data processing completed');
            } else {
                foreach ($tasks as $task) {
                    $output->writeLine("• $task", ConsoleColor::GRAY);
                    usleep(800000);
                }
            }
        }

        $output->writeLine("✅ Spinner demo completed!", ConsoleColor::GREEN);

        return ExitCode::SUCCESS;
    }
}
