<?php
/**
 * Advanced Database Migration Runner for API Module
 * Supports both upgrades and rollbacks
 */

// Define necessary constants
define('BASEPATH', true);
define('APPPATH', '../application/');
define('ENVIRONMENT', 'production');

class APIMigrationRunner
{
    private $CI;
    private $module_name = 'api';
    private $migration_path = 'migrations/';

    public function __construct()
    {
        // Load Perfex CRM framework
        require_once '../../index.php';
        $this->CI =& get_instance();
    }

    public function run($target_version = null, $rollback = false)
    {
        $this->print_header();

        // Validate environment
        if (!$this->validate_environment()) {
            return false;
        }

        // Get current version
        $current_version = $this->get_current_version();
        echo "📊 Current migration version: $current_version\n\n";

        // Get available migrations
        $migrations = $this->get_available_migrations();

        if ($rollback) {
            return $this->run_rollback($current_version, $target_version, $migrations);
        } else {
            return $this->run_upgrade($current_version, $target_version, $migrations);
        }
    }

    private function validate_environment()
    {
        // Check if API module is active
        if (!$this->CI->app_modules->is_active($this->module_name)) {
            echo "❌ ERROR: API module is not active. Please activate it first.\n";
            echo "   Go to Admin → Setup → Modules and activate the API module.\n\n";
            return false;
        }

        echo "✅ API module is active\n";

        // Check database connection
        if (!isset($this->CI->db) || !$this->CI->db->conn_id) {
            echo "❌ ERROR: Database connection failed\n";
            return false;
        }

        echo "✅ Database connection established\n";
        return true;
    }

    private function get_current_version()
    {
        $migration_table = db_prefix() . 'migrations';

        if ($this->CI->db->table_exists('migrations')) {
            $result = $this->CI->db->select('version')
                                  ->from('migrations')
                                  ->where('module', $this->module_name)
                                  ->get();

            if ($result->num_rows() > 0) {
                return $result->row()->version;
            }
        }

        return 0;
    }

    private function get_available_migrations()
    {
        $migrations = [];

        // Scan migration files
        $files = glob($this->migration_path . '*_version_*.php');

        foreach ($files as $file) {
            if (preg_match('/(\d+)_version_(\d+)\.php$/', basename($file), $matches)) {
                $version = (int) $matches[1];
                $migrations[$version] = [
                    'file' => $file,
                    'class' => 'Migration_Version_' . $matches[1]
                ];
            }
        }

        ksort($migrations);
        return $migrations;
    }

    private function run_upgrade($current_version, $target_version, $migrations)
    {
        // Determine which migrations to run
        $migrations_to_run = [];
        foreach ($migrations as $version => $migration) {
            if ($version > $current_version && ($target_version === null || $version <= $target_version)) {
                $migrations_to_run[$version] = $migration;
            }
        }

        if (empty($migrations_to_run)) {
            echo "✅ All migrations are up to date!\n\n";
            return true;
        }

        echo "📋 Migrations to run:\n";
        foreach ($migrations_to_run as $version => $migration) {
            echo "   - Version $version: {$migration['class']}\n";
        }
        echo "\n";

        // Confirm execution
        if (!$this->confirm_execution()) {
            return false;
        }

        // Execute migrations
        return $this->execute_migrations($migrations_to_run, 'up');
    }

    private function run_rollback($current_version, $target_version, $migrations)
    {
        // Determine rollback target
        $target = $target_version ?? 0;

        if ($target >= $current_version) {
            echo "❌ ERROR: Target version ($target) must be less than current version ($current_version)\n";
            return false;
        }

        // Find migrations to rollback
        $migrations_to_rollback = [];
        foreach (array_reverse($migrations, true) as $version => $migration) {
            if ($version > $target && $version <= $current_version) {
                $migrations_to_rollback[$version] = $migration;
            }
        }

        if (empty($migrations_to_rollback)) {
            echo "✅ No migrations to rollback!\n\n";
            return true;
        }

        echo "📋 Migrations to rollback:\n";
        foreach ($migrations_to_rollback as $version => $migration) {
            echo "   - Version $version: {$migration['class']}\n";
        }
        echo "\n";

        // Confirm execution
        if (!$this->confirm_execution('rollback')) {
            return false;
        }

        // Execute rollbacks
        return $this->execute_migrations($migrations_to_rollback, 'down');
    }

    private function confirm_execution($action = 'upgrade')
    {
        if (php_sapi_name() === 'cli') {
            echo "Do you want to $action these migrations? (y/N): ";
            $handle = fopen("php://stdin", "r");
            $response = trim(fgets($handle));
            fclose($handle);

            if (strtolower($response) !== 'y' && strtolower($response) !== 'yes') {
                echo "Migration $action cancelled.\n";
                return false;
            }
        }

        return true;
    }

    private function execute_migrations($migrations, $method)
    {
        $success_count = 0;
        $error_count = 0;

        foreach ($migrations as $version => $migration) {
            echo "🔄 Running migration {$migration['class']}::$method()...\n";

            try {
                // Load migration file
                if (!file_exists($migration['file'])) {
                    throw new Exception("Migration file not found: {$migration['file']}");
                }

                require_once $migration['file'];

                // Instantiate migration class
                if (!class_exists($migration['class'])) {
                    throw new Exception("Migration class not found: {$migration['class']}");
                }

                $migration_instance = new $migration['class']();

                // Run the method
                if (!method_exists($migration_instance, $method)) {
                    throw new Exception("Method $method() not found in migration class");
                }

                $migration_instance->$method();
                echo "   ✅ Migration completed successfully\n";

                // Update migration version in database
                if ($method === 'up') {
                    $this->CI->db->replace('migrations', [
                        'module' => $this->module_name,
                        'version' => $version
                    ]);
                } elseif ($method === 'down') {
                    // For rollback, set to previous version
                    $prev_version = $this->get_previous_version($version, $migrations);
                    if ($prev_version === null) {
                        $this->CI->db->delete('migrations', ['module' => $this->module_name]);
                    } else {
                        $this->CI->db->replace('migrations', [
                            'module' => $this->module_name,
                            'version' => $prev_version
                        ]);
                    }
                }

                $success_count++;

            } catch (Exception $e) {
                echo "   ❌ Migration failed: " . $e->getMessage() . "\n";
                $error_count++;
            }

            echo "\n";
        }

        // Summary
        $action_name = ($method === 'up') ? 'upgrade' : 'rollback';
        echo "📊 Migration Summary ($action_name):\n";
        echo "   ✅ Successful: $success_count\n";
        echo "   ❌ Failed: $error_count\n\n";

        if ($error_count > 0) {
            echo "⚠️  Some migrations failed. Please check the errors above.\n";
            return false;
        } else {
            echo "🎉 All migrations completed successfully!\n";
            echo "   API module database is now " . ($method === 'up' ? 'up to date' : 'rolled back') . ".\n";
            return true;
        }
    }

    private function get_previous_version($current_version, $migrations)
    {
        $versions = array_keys($migrations);
        sort($versions);

        $index = array_search($current_version, $versions);
        if ($index === false || $index === 0) {
            return null;
        }

        return $versions[$index - 1];
    }

    private function print_header()
    {
        echo "🚀 API Module Database Migration Runner\n";
        echo "=======================================\n\n";
    }
}

// CLI Interface
if (php_sapi_name() === 'cli') {
    $options = getopt('t:r', ['target:', 'rollback']);

    $target_version = isset($options['t']) ? (int)$options['t'] : (isset($options['target']) ? (int)$options['target'] : null);
    $rollback = isset($options['r']) || isset($options['rollback']);

    $runner = new APIMigrationRunner();
    $success = $runner->run($target_version, $rollback);

    exit($success ? 0 : 1);
} else {
    // Web interface
    echo "<pre>";
    $runner = new APIMigrationRunner();
    $runner->run();
    echo "</pre>";
}
?>