#!/usr/bin/env php
<?php

/**
 * Meezak Framework Artisan CLI
 *
 * Command runner for framework operations like migrations.
 */

// Bootstrap
$app = require_once __DIR__ . '/bootstrap.php';

// Get command and arguments
$command = $argv[1] ?? null;
$args = array_slice($argv, 2);

if (!$command) {
    showHelp();
    exit(0);
}

// Service instances
$db = $app->resolve(\Core\Database::class);
$logger = $app->resolve(\Core\Logger::class);
$migrationsPath = BASE_PATH . '/migrations';

$migrator = new \Core\Migrations\Migrator($db, $logger, $migrationsPath);

try {
    switch ($command) {
        case 'migrate':
            handleMigrate($migrator, $args);
        break;

        case 'migrate:rollback':
            handleRollback($migrator, $args);
        break;

        case 'migrate:reset':
            handleReset($migrator);
        break;

        case 'migrate:refresh':
            handleRefresh($migrator);
        break;

        case 'migrate:status':
            handleStatus($migrator);
        break;

        case 'migrate:one':
            handleMigrateOne($migrator, $args);
        break;

        case 'make:migration':
            handleMakeMigration($args, $migrationsPath);
        break;

        case 'help':
        case '--help':
        case '-h':
            showHelp();
        break;

        default:
            echo "Unknown command: {$command}\n";
            showHelp();
            exit(1);
    }
} catch (\Exception $e) {
    echo "\n❌ Error: {$e->getMessage()}\n";
    exit(1);
}

exit(0);

// ============================================================================
// Command Handlers
// ============================================================================

function resolveMigrationTarget(array $args): ?string
{
    $target = null;

    foreach ($args as $arg) {

        // --path=migrations/file.php
        if (str_starts_with($arg, '--path=')) {
            $target = substr($arg, 7);
            break;
        }

        // ignore flags
        if ($arg === '--force') {
            continue;
        }

        // first non-flag argument
        if (!str_starts_with($arg, '--')) {
            $target = $arg;
            break;
        }
    }

    if (!$target) {
        return null;
    }

    // normalize input
    $target = str_replace('.php', '', $target);
    $target = str_replace('migrations/', '', $target);

    return $target;
}


function handleMigrate(\Core\Migrations\Migrator $migrator, array $args): void
{
    $target = resolveMigrationTarget($args);

    // If user passed a file → run single migration
    if ($target) {
        echo "\n🚀 Running single migration: {$target}\n";

        try {
            $resolved = $migrator->migrateOne(
                $target,
                in_array('--force', $args, true)
            );

            echo "\n✅ Executed migration: {$resolved}\n\n";
        } catch (\Exception $e) {
            echo "\n❌ {$e->getMessage()}\n\n";
            exit(1);
        }

        return;
    }

    // Otherwise run all migrations
    echo "\n🚀 Running migrations...\n";

    $executed = $migrator->migrate();

    if (empty($executed)) {
        echo "✅ No pending migrations.\n\n";
        return;
    }

    echo "\n✅ Executed " . count($executed) . " migration(s):\n";
    foreach ($executed as $migration) {
        echo "  • {$migration}\n";
    }

    echo "\n";
}

function handleRollback(\Core\Migrations\Migrator $migrator, array $args): void
{
    $steps = isset($args[0]) && is_numeric($args[0]) ? (int)$args[0] : 1;

    echo "\n⏮️  Rolling back {$steps} batch(es)...\n";
    $rolled = $migrator->rollback($steps);

    if (empty($rolled)) {
        echo "✅ No migrations to rollback.\n\n";
        return;
    }

    echo "\n✅ Rolled back " . count($rolled) . " migration(s):\n";
    foreach ($rolled as $migration) {
        echo "  • {$migration}\n";
    }
    echo "\n";
}

function handleReset(\Core\Migrations\Migrator $migrator): void
{
    echo "\n🔄 Resetting all migrations...\n";
    $rolled = $migrator->reset();

    if (empty($rolled)) {
        echo "✅ No migrations to reset.\n\n";
        return;
    }

    echo "\n✅ Reset " . count($rolled) . " migration(s):\n";
    foreach ($rolled as $migration) {
        echo "  • {$migration}\n";
    }
    echo "\n";
}

function handleRefresh(\Core\Migrations\Migrator $migrator): void
{
    echo "\n♻️  Refreshing migrations (reset + migrate)...\n";
    $migrator->reset();
    $executed = $migrator->migrate();

    echo "\n✅ Refreshed " . count($executed) . " migration(s):\n";
    foreach ($executed as $migration) {
        echo "  • {$migration}\n";
    }
    echo "\n";
}

function handleStatus(\Core\Migrations\Migrator $migrator): void
{
    $status = $migrator->getStatus();

    echo "\n📋 Migration Status:\n\n";
    echo sprintf("%-50s %s\n", "Migration", "Status");
    echo str_repeat("-", 60) . "\n";

    foreach ($status as $migration => $state) {
        $icon = $state === 'Executed' ? '✅' : '⏳';
        echo sprintf("%s %-48s %s\n", $icon, $migration, $state);
    }
    echo "\n";
}

function handleMigrateOne(\Core\Migrations\Migrator $migrator, array $args): void
{
    $target = resolveMigrationTarget($args);

    if (!$target) {
        echo "❌ Migration name is required.\n";
        echo "Usage: php artisan migrate:one <name|file> [--force]\n";
        exit(1);
    }

    try {
        $resolved = $migrator->migrateOne(
            $target,
            in_array('--force', $args, true)
        );

        echo "\n✅ Executed migration: {$resolved}\n\n";
    } catch (\Exception $e) {
        echo "\n❌ {$e->getMessage()}\n\n";
        exit(1);
    }
}

function handleMakeMigration(array $args, string $migrationsPath): void
{
    if (empty($args[0])) {
        echo "❌ Migration name is required.\n";
        echo "Usage: php artisan make:migration <name>\n";
        echo "Example: php artisan make:migration create_users_table\n";
        exit(1);
    }

    $name = $args[0];

    // Validate name
    if (!preg_match('/^[a-z_]+$/', $name)) {
        echo "❌ Migration name must contain only lowercase letters and underscores.\n";
        exit(1);
    }

    // Generate timestamp filename
    $timestamp = date('Y_m_d_His');
    $className = implode('', array_map('ucfirst', explode('_', $name)));
    $filename = "{$timestamp}_{$name}.php";
    $filePath = $migrationsPath . '/' . $filename;

    // Create template
    $template = <<<'PHP'
<?php

namespace Migrations;

use Core\Migrations\Migration;

class {CLASS_NAME} extends Migration
{
    public function up(): void
    {
        // TODO: Define your schema changes
        $this->create('{TABLE_NAME}', function ($table) {
            $table->id();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        $this->drop('{TABLE_NAME}');
    }
}
PHP;

    $tableName = str_replace('_table', '', $name);
    $tableName = preg_replace('/^create_/', '', $tableName);

    $content = str_replace(
        ['{CLASS_NAME}', '{TABLE_NAME}'],
        [$className, $tableName],
        $template
    );

    if (!is_dir($migrationsPath)) {
        mkdir($migrationsPath, 0755, true);
    }

    file_put_contents($filePath, $content);

    echo "\n✅ Migration created: {$filename}\n";
    echo "📝 Location: {$filePath}\n\n";
}

function showHelp(): void
{
    echo <<<'HELP'

  Meezak Framework Artisan CLI

  Usage:
    php artisan <command> [arguments]

  Available Commands:

    Migration Commands:
      migrate                      Run all pending migrations
      migrate:one <name> [--force] Run a single specific migration
      migrate:rollback [n]         Rollback last N batches (default: 1)
      migrate:reset                Rollback all migrations
      migrate:refresh              Reset and re-run all migrations
      migrate:status               Show migration status
      make:migration <name>        Create a new migration file

    Other:
      help, --help, -h        Show this help message

  Examples:
    php artisan migrate
    php artisan migrate:one create_otps_table
    php artisan migrate:one 2024_01_15_120530_create_otps_table
    php artisan migrate:one create_otps_table --force
    php artisan migrate:rollback 2
    php artisan make:migration create_users_table
    php artisan migrate:status

HELP;
}
