<?php
/**
 * Migration Manager
 *
 * Central manager for all plugin migrations.
 *
 * @package     Havenlytics
 * @subpackage  Core\Migration
 * @since       2.1.3
 */

namespace HvnlyNab\Core\Migration;

// Prevent direct access.
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Class Migrator
 *
 * Manages the execution of version migrations in order.
 * Uses WordPress options to track completed migrations.
 *
 * @since 2.1.3
 */
class Migrator {

    /**
     * Option key for tracking completed migrations.
     *
     * @var string
     */
    const COMPLETED_KEY = 'hvnly_migrations_completed';

    /**
     * Registered migration handlers.
     *
     * @var array
     */
    private static $migrations = array();

    /**
     * Initialize the migrator and register migrations.
     *
     * @since 2.1.3
     * @return void
     */
    public static function init() {
        // Register migration handlers in version order.
        self::register('2.1.3', Handlers\Version213Handler::class);
        // Add future migrations here:
        // self::register('2.2.0', Handlers\Version220Handler::class);
        // self::register('2.3.0', Handlers\Version230Handler::class);
    }

    /**
     * Register a migration handler.
     *
     * @since 2.1.3
     * @param string $version Target version.
     * @param string $class   Handler class name.
     * @return void
     */
    public static function register(string $version, string $class) {
        self::$migrations[$version] = $class;
    }

    /**
     * Run all pending migrations.
     *
     * @since 2.1.3
     * @return bool True on success, false on failure.
     */
    public static function run(): bool {
        // Initialize migrations if not done yet.
        if (empty(self::$migrations)) {
            self::init();
        }

        $completed = get_option(self::COMPLETED_KEY, array());
        $all_success = true;
        $current_version = HVNLYNAB_VERSION;

        // Sort migrations by version (ascending).
        ksort(self::$migrations);

        foreach (self::$migrations as $version => $handler_class) {
            // Skip if version is greater than current plugin version.
            if (version_compare($version, $current_version, '>')) {
                continue;
            }

            // Skip if already completed.
            if (isset($completed[$version]) && $completed[$version] === true) {
                continue;
            }

            // Run the migration.
            $success = self::run_migration($version, $handler_class);

            if ($success) {
                $completed[$version] = true;
                update_option(self::COMPLETED_KEY, $completed);
            } else {
                $all_success = false;
                break;
            }
        }

        return $all_success;
    }

    /**
     * Execute a single migration.
     *
     * @since 2.1.3
     * @param string $version      Target version.
     * @param string $handler_class Handler class.
     * @return bool True on success, false on failure.
     */
    private static function run_migration(string $version, string $handler_class): bool {
        if (!class_exists($handler_class)) {
            return false;
        }

        $handler = new $handler_class();

        // Verify the handler implements the required interface.
        if (!($handler instanceof Interfaces\MigrationInterface)) {
            return false;
        }

        // Check if migration is needed.
        if (!$handler->is_needed()) {
            return true;
        }

        // Execute the migration.
        return $handler->up();
    }

    /**
     * Get migration status.
     *
     * @since 2.1.3
     * @return array Migration status information.
     */
    public static function get_status(): array {
        if (empty(self::$migrations)) {
            self::init();
        }

        $completed = get_option(self::COMPLETED_KEY, array());

        $status = array(
            'total'       => count(self::$migrations),
            'completed'   => 0,
            'pending'     => array(),
            'migrations'  => array(),
        );

        foreach (self::$migrations as $version => $handler_class) {
            $is_completed = isset($completed[$version]) && $completed[$version] === true;
            $status['migrations'][$version] = array(
                'version'   => $version,
                'completed' => $is_completed,
                'handler'   => $handler_class,
            );

            if ($is_completed) {
                $status['completed']++;
            } else {
                $status['pending'][] = $version;
            }
        }

        return $status;
    }

    /**
     * Force re-run all migrations (for debugging).
     *
     * @since 2.1.3
     * @return void
     */
    public static function reset() {
        delete_option(self::COMPLETED_KEY);
    }
}