<?php
/**
 * Integration Loader Class
 *
 * @package FleekDash
 * @subpackage Integrations\Core
 */

namespace FleekDash\Integrations\Core;

use FleekDash\Traits\Base;

defined('ABSPATH') || exit;

/**
 * Integration Loader class
 *
 * Responsible for loading and initializing active integrations with REST routes
 */
class IntegrationLoader
{
    use Base;

    /**
     * Loaded integrations
     *
     * @var array
     */
    private array $loadedIntegrations = [];

    /**
     * Constructor
     */
    private function __construct()
    {
        // Register hooks for loading integrations
        add_action('plugins_loaded', [$this, 'loadActiveIntegrations'], 10);
        add_action('rest_api_init', [$this, 'registerIntegrationRoutes'], 5);
        add_action('init', [$this, 'initializeIntegrations'], 15);
    }

    /**
     * Load active integrations
     *
     * @return void
     */
    public function loadActiveIntegrations(): void
    {
        error_log('IntegrationLoader: Loading active integrations...');

        $activeIntegrations = get_option('fleekdash_active_integrations', []);
        $activeIntegrations = is_array($activeIntegrations) ? $activeIntegrations : [];
        error_log('IntegrationLoader: Active integrations from DB: ' . json_encode($activeIntegrations));

        if (empty($activeIntegrations)) {
            error_log('IntegrationLoader: No active integrations found');
            return;
        }

        // Load each active integration
        foreach ($activeIntegrations as $integrationId) {
            $this->loadIntegration((string) $integrationId);
        }
    }

    /**
     * Load a single integration
     *
     * @param string $integrationId Integration ID
     * @return bool Success
     */
    private function loadIntegration(string $integrationId): bool
    {
        error_log("IntegrationLoader: Loading integration: $integrationId");
        $loaded = false;

        try {
            // Get integration class name
            $className = $this->getIntegrationClassName($integrationId);

            if (!class_exists($className)) {
                // Try to load the integration file
                $integrationFile = $this->getIntegrationFilePath($integrationId);

                if (file_exists($integrationFile)) {
                    require_once $integrationFile;
                    error_log("IntegrationLoader: Loaded file for $integrationId: $integrationFile");
                } else {
                    error_log("IntegrationLoader: Integration file not found: $integrationFile");
                }
            }

            if (class_exists($className)) {
                // Instantiate the integration with the integration directory
                $integrationDir = FLEEKDASH_PLUGIN_DIR . "integrations/{$integrationId}";
                $integration = new $className($integrationDir);

                // Store the integration instance
                $this->loadedIntegrations[$integrationId] = $integration;

                error_log("IntegrationLoader: Successfully loaded integration: $integrationId");
                $loaded = true;
            } else {
                error_log("IntegrationLoader: Class not found: $className");
            }

        } catch (\Exception $e) {
            error_log("IntegrationLoader: Error loading integration $integrationId: " . $e->getMessage());
        }

        return $loaded;
    }

    /**
     * Register REST routes for all loaded integrations
     *
     * @return void
     */
    public function registerIntegrationRoutes(): void
    {
        error_log('IntegrationLoader: Registering REST routes for loaded integrations...');

        foreach ($this->loadedIntegrations as $integrationId => $integration) {
            try {
                if (method_exists($integration, 'registerRestRoutes')) {
                    $integration->registerRestRoutes();
                    error_log("IntegrationLoader: Registered REST routes for: $integrationId");
                }
            } catch (\Exception $e) {
                error_log("IntegrationLoader: Error registering REST routes for $integrationId: " . $e->getMessage());
            }
        }
    }

    /**
     * Initialize all loaded integrations
     *
     * @return void
     */
    public function initializeIntegrations(): void
    {
        error_log('IntegrationLoader: Initializing loaded integrations...');

        foreach ($this->loadedIntegrations as $integrationId => $integration) {
            try {
                // Check if integration is available
                if (method_exists($integration, 'isAvailable') && !$integration->isAvailable()) {
                    error_log("IntegrationLoader: Integration $integrationId is not available, skipping initialization");
                    continue;
                }

                // Initialize the integration
                if (method_exists($integration, 'init')) {
                    $integration->init();
                    error_log("IntegrationLoader: Initialized integration: $integrationId");
                }

                // Register hooks
                if (method_exists($integration, 'registerHooks')) {
                    $integration->registerHooks();
                    error_log("IntegrationLoader: Registered hooks for: $integrationId");
                }

            } catch (\Exception $e) {
                error_log("IntegrationLoader: Error initializing $integrationId: " . $e->getMessage());
            }
        }
    }

    /**
     * Get integration class name from ID
     *
     * @param string $integrationId Integration ID
     * @return string Class name
     */
    private function getIntegrationClassName(string $integrationId): string
    {
        // Convert kebab-case to PascalCase
        $parts = explode('-', $integrationId);
        $classParts = array_map('ucfirst', $parts);
        $className = implode('', $classParts);

        return "FleekDash\\Integrations\\{$className}\\Integration";
    }

    /**
     * Get integration file path
     *
     * @param string $integrationId Integration ID
     * @return string File path
     */
    private function getIntegrationFilePath(string $integrationId): string
    {
        return FLEEKDASH_PLUGIN_DIR . "integrations/{$integrationId}/Integration.php";
    }

    /**
     * Get loaded integrations
     *
     * @return array
     */
    public function getLoadedIntegrations(): array
    {
        return $this->loadedIntegrations;
    }

    /**
     * Get a specific loaded integration
     *
     * @param string $integrationId Integration ID
     * @return object|null Integration instance
     */
    public function getIntegration(string $integrationId): ?object
    {
        return $this->loadedIntegrations[$integrationId] ?? null;
    }

    /**
     * Check if an integration is loaded
     *
     * @param string $integrationId Integration ID
     * @return bool
     */
    public function isIntegrationLoaded(string $integrationId): bool
    {
        return isset($this->loadedIntegrations[$integrationId]);
    }
}
