<?php

namespace FleekDash\Integrations\Core;

defined('ABSPATH') || exit;

/**
 * Safe Bootstrap Class
 *
 * Handles initialization in a safer way to avoid circular dependencies
 */
class SafeBootstrap
{
    private const REST_NAMESPACE = 'fleekdash/v1';

    private static ?SafeBootstrap $instance = null;
    private bool $initialized = false;
    private array $integrations = [];

    private function __construct()
    {
        // Empty constructor to avoid early initialization
    }

    public static function getInstance(): SafeBootstrap
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Initialize the system safely
     */
    public function init(): void
    {
        if ($this->initialized) {
            return;
        }

        try {
            $this->registerRestRoutes();
            $this->discoverIntegrations();
            $this->loadActiveIntegrations();
            $this->initialized = true;
        } catch (\Exception $e) {
            error_log('SafeBootstrap Error: ' . $e->getMessage());
        }
    }

    /**
     * Register REST API routes directly
     */
    private function registerRestRoutes(): void
    {
        add_action('rest_api_init', function () {
            // Main integrations endpoint
            register_rest_route(self::REST_NAMESPACE, '/integrations', [
                'methods' => 'GET',
                'callback' => [$this, 'getIntegrations'],
                'permission_callback' => function () {
                    return current_user_can('manage_options');
                }
            ]);

            // Activation endpoint
            register_rest_route(self::REST_NAMESPACE, '/integrations/(?P<id>[a-zA-Z0-9-_]+)/activate', [
                'methods' => 'POST',
                'callback' => [$this, 'activateIntegration'],
                'permission_callback' => function () {
                    return current_user_can('manage_options');
                }
            ]);

            // Deactivation endpoint
            register_rest_route(self::REST_NAMESPACE, '/integrations/(?P<id>[a-zA-Z0-9-_]+)/deactivate', [
                'methods' => 'POST',
                'callback' => [$this, 'deactivateIntegration'],
                'permission_callback' => function () {
                    return current_user_can('manage_options');
                }
            ]);
        });
    }

    /**
     * Discover integrations without complex dependencies
     */
    private function discoverIntegrations(): void
    {
        $integrationsPath = FLEEKDASH_PLUGIN_DIR . 'integrations';
        $dirs = glob($integrationsPath . '/*', GLOB_ONLYDIR);

        foreach ($dirs as $dir) {
            if (basename($dir) === 'Core') {
                continue;
            }

            $integration = $this->scanIntegration($dir);
            if ($integration) {
                $this->integrations[$integration['id']] = $integration;
            }
        }
    }

    /**
     * Scan single integration directory
     */
    private function scanIntegration(string $path): ?array
    {
        $configFile = $path . '/config.json';

        if (!file_exists($configFile)) {
            return null;
        }

        $config = json_decode(file_get_contents($configFile), true);
        if (!$config || empty($config['id'])) {
            return null;
        }

        return [
            'id' => $config['id'],
            'name' => $config['name'] ?? '',
            'description' => $config['description'] ?? '',
            'version' => $config['version'] ?? '1.0.0',
            'category' => $config['category'] ?? 'plugin',
            'requires' => $config['requires'] ?? [],
            'path' => $path,
            'config' => $config
        ];
    }

    /**
     * REST API: Get integrations
     */
    public function getIntegrations(): \WP_REST_Response
    {
        $active = get_option('fleekdash_active_integrations', []);

        // Ensure we have an array
        if (!is_array($active)) {
            $active = [];
        }

        // Filter out any invalid entries
        $active = array_filter($active, 'is_string');

        // Organize by category
        $categorized = [
            'plugin' => [],
            'theme' => [],
            'api' => []
        ];

        foreach ($this->integrations as $integration) {
            $category = $integration['category'];
            if ($category === 'ecommerce') {
                $category = 'plugin'; // Map ecommerce to plugin for UI
            }

            if (!isset($categorized[$category])) {
                $categorized[$category] = [];
            }

            $categorized[$category][] = [
                'id' => $integration['id'],
                'name' => $integration['name'],
                'description' => $integration['description'],
                'version' => $integration['version'],
                'category' => $integration['category'],
                'is_active' => in_array($integration['id'], $active),
                'is_installed' => true,
                'is_available' => $this->checkRequirements($integration['requires']),
                'slug' => $integration['id']
            ];
        }

        return rest_ensure_response($categorized);
    }

    /**
     * REST API: Activate integration
     */
    public function activateIntegration(\WP_REST_Request $request): \WP_REST_Response|\WP_Error
    {
        $id = $request->get_param('id');

        // Validate the ID
        if (!is_string($id) || empty($id)) {
            return new \WP_Error('invalid_id', 'Invalid integration ID', ['status' => 400]);
        }

        $active = get_option('fleekdash_active_integrations', []);

        // Ensure we have an array
        if (!is_array($active)) {
            $active = [];
        }

        if (!in_array($id, $active)) {
            $active[] = $id;
            update_option('fleekdash_active_integrations', $active);
        }

        return rest_ensure_response(['success' => true]);
    }

    /**
     * REST API: Deactivate integration
     */
    public function deactivateIntegration(\WP_REST_Request $request): \WP_REST_Response|\WP_Error
    {
        $id = $request->get_param('id');

        // Validate the ID
        if (!is_string($id) || empty($id)) {
            return new \WP_Error('invalid_id', 'Invalid integration ID', ['status' => 400]);
        }

        $active = get_option('fleekdash_active_integrations', []);

        // Ensure we have an array
        if (!is_array($active)) {
            $active = [];
        }

        $active = array_filter($active, function ($integrationId) use ($id) {
            return is_string($integrationId) && $integrationId !== $id;
        });

        update_option('fleekdash_active_integrations', array_values($active));

        return rest_ensure_response(['success' => true]);
    }

    /**
     * Check integration requirements
     */
    private function checkRequirements(array $requires): bool
    {
        $phpOk = !isset($requires['php']) || version_compare(PHP_VERSION, $requires['php'], '>=');
        $wordpressOk = !isset($requires['wordpress'])
            || version_compare(get_bloginfo('version'), $requires['wordpress'], '>=');
        $pluginsOk = !isset($requires['plugins']) || $this->areRequiredPluginsActive($requires['plugins']);

        return $phpOk && $wordpressOk && $pluginsOk;
    }

    /**
     * @param array<int, string> $plugins
     */
    private function areRequiredPluginsActive(array $plugins): bool
    {
        $allActive = true;
        foreach ($plugins as $plugin) {
            if (!is_plugin_active($plugin)) {
                $allActive = false;
                break;
            }
        }
        return $allActive;
    }

    /**
     * Load and initialize active integrations
     */
    private function loadActiveIntegrations(): void
    {
        $active = get_option('fleekdash_active_integrations', []);

        // Ensure we have an array and it's not corrupted
        if (!is_array($active)) {
            error_log('fleekdash_active_integrations is not an array, resetting to empty array');
            $active = [];
            update_option('fleekdash_active_integrations', $active);
            return;
        }

        foreach ($active as $integrationId) {
            // Ensure integrationId is a valid string
            if (!is_string($integrationId) || empty($integrationId)) {
                error_log("Invalid integration ID found in active integrations: " . print_r($integrationId, true));
                continue;
            }

            if (!isset($this->integrations[$integrationId])) {
                continue; // Skip if integration not discovered
            }

            $integration = $this->integrations[$integrationId];

            try {
                $this->loadIntegration($integration);
            } catch (\Exception $e) {
                error_log("Failed to load integration {$integrationId}: " . $e->getMessage());
            }
        }
    }

    /**
     * Load a single integration
     */
    private function loadIntegration(array $integration): bool // NOSONAR php:S3776 - Bootstrapping flow needs explicit guarded steps and logging for recovery.
    {
        $loaded = false;
        $integrationFile = $integration['path'] . '/Integration.php';

        if (file_exists($integrationFile)) {
            // Load the integration file
            require_once $integrationFile;

            // Get class name based on integration ID
            $className = $this->getIntegrationClassName($integration['id']);

            if (class_exists($className)) {
                try {
                    // Create integration instance with the directory path
                    $instance = new $className($integration['path']);

                    // Check if it has the expected methods and call them
                    if (method_exists($instance, 'init')) {
                        $instance->init();
                    }

                    if (method_exists($instance, 'registerHooks')) {
                        $instance->registerHooks();
                    }

                    if (method_exists($instance, 'registerRestRoutes')) {
                        add_action('rest_api_init', [$instance, 'registerRestRoutes']);
                    }

                    error_log("Successfully loaded integration: {$integration['id']}");
                    $loaded = true;
                } catch (\Exception $e) {
                    error_log("Error initializing integration {$integration['id']}: " . $e->getMessage());
                }
            } else {
                error_log("Integration class not found: {$className}");
            }
        } else {
            error_log("Integration file not found: {$integrationFile}");
        }

        return $loaded;
    }

    /**
     * Get integration class name from ID
     */
    private function getIntegrationClassName(string $integrationId): string
    {
        // Convert kebab-case to PascalCase
        $className = str_replace(' ', '', ucwords(str_replace('-', ' ', $integrationId)));
        return "FleekDash\\Integrations\\{$className}\\Integration";
    }

    /**
     * Get discovered integrations
     */
    public function getDiscoveredIntegrations(): array
    {
        return $this->integrations;
    }
}
