<?php

namespace FleekDash\Integrations\Core;

defined('ABSPATH') || exit;

/**
 * Cloud Integration Manager
 *
 * Handles discovery, download, and installation of MU plugin integrations
 * from the FleekDash Cloud Registry
 */
class CloudIntegrationManager
{
    private string $cloudApiUrl = 'https://api.fleekdash.com/v2/integrations';
    private string $muPluginsPath;
    private string $cacheKey = 'fleekdash_cloud_integrations';

    public function __construct()
    {
        $this->muPluginsPath = WP_CONTENT_DIR . '/mu-plugins';
    }

    /**
     * Discover all available integrations (local + cloud)
     */
    public function discoverIntegrations(): array
    {
        $localIntegrations = $this->scanLocalMUIntegrations();
        $cloudIntegrations = $this->fetchCloudIntegrations();

        return $this->mergeIntegrations($localIntegrations, $cloudIntegrations);
    }

    /**
     * Scan local MU plugins for FleekDash integrations
     */
    private function scanLocalMUIntegrations(): array
    {
        $integrations = [];
        $pattern = $this->muPluginsPath . '/fleekdash-integration-*/';
        $directories = glob($pattern, GLOB_ONLYDIR);

        foreach ($directories as $dir) {
            $configFile = $dir . '/config.json';

            if (file_exists($configFile)) {
                $config = json_decode(file_get_contents($configFile), true);

                if ($config && isset($config['id'])) {
                    $integrations[$config['id']] = [
                        'id' => $config['id'],
                        'name' => $config['name'] ?? $config['id'],
                        'description' => $config['description'] ?? '',
                        'version' => $config['version'] ?? '1.0.0',
                        'author' => $config['author'] ?? 'Unknown',
                        'category' => $config['category'] ?? 'utility',
                        'status' => 'installed',
                        'type' => 'local',
                        'path' => $dir,
                        'entry_file' => $this->findEntryFile($dir),
                        'config' => $config,
                        'active' => $this->isIntegrationActive($config['id']),
                        'priority' => $config['priority'] ?? 10,
                        'dependencies' => $config['dependencies'] ?? []
                    ];
                }
            }
        }

        return $integrations;
    }

    /**
     * Fetch cloud integrations from FleekDash API
     */
    private function fetchCloudIntegrations(): array
    {
        $cached = get_transient($this->cacheKey);
        if ($cached && is_array($cached)) {
            return $cached;
        }

        $response = wp_remote_get($this->cloudApiUrl, [
            'timeout' => 10,
            'headers' => [
                'User-Agent' => 'FleekDash/' . FLEEKDASH_VERSION,
                'Accept' => 'application/json'
            ]
        ]);

        if (is_wp_error($response)) {
            error_log('FleekDash: Failed to fetch cloud integrations: ' . $response->get_error_message());
            return [];
        }

        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);

        if (!$data || !isset($data['integrations'])) {
            return [];
        }

        $integrations = [];
        foreach ($data['integrations'] as $integration) {
            $integrations[$integration['id']] = [
                'id' => $integration['id'],
                'name' => $integration['name'],
                'description' => $integration['description'],
                'version' => $integration['version'],
                'author' => $integration['author'],
                'category' => $integration['category'],
                'status' => 'available',
                'type' => 'cloud',
                'download_url' => $integration['download_url'],
                'file_size' => $integration['file_size'],
                'requires' => $integration['requires'] ?? [],
                'dependencies' => $integration['dependencies'] ?? [],
                'priority' => $integration['priority'] ?? 10,
                'featured' => $integration['featured'] ?? false,
                'price' => $integration['price'] ?? 0,
                'active' => false
            ];
        }

        // Cache for 1 hour
        set_transient($this->cacheKey, $integrations, HOUR_IN_SECONDS);

        return $integrations;
    }

    /**
     * Merge local and cloud integrations
     */
    private function mergeIntegrations(array $local, array $cloud): array
    {
        $merged = [];

        // Add local integrations first
        foreach ($local as $id => $integration) {
            $merged[$id] = $integration;
        }

        // Add cloud integrations that aren't installed locally
        foreach ($cloud as $id => $integration) {
            if (!isset($merged[$id])) {
                $merged[$id] = $integration;
            } else {
                // Check for updates
                $localVersion = $merged[$id]['version'];
                $cloudVersion = $integration['version'];

                if (version_compare($cloudVersion, $localVersion, '>')) {
                    $merged[$id]['update_available'] = true;
                    $merged[$id]['latest_version'] = $cloudVersion;
                }
            }
        }

        return $merged;
    }

    /**
     * Install integration from cloud
     */
    public function installIntegration(string $integrationId): bool
    {
        $cloudIntegrations = $this->fetchCloudIntegrations();

        if (!isset($cloudIntegrations[$integrationId])) {
            return false;
        }

        $integration = $cloudIntegrations[$integrationId];
        $downloadUrl = $integration['download_url'];

        // Create integration directory
        $integrationDir = $this->muPluginsPath . '/fleekdash-integration-' . $integrationId;

        if (!wp_mkdir_p($integrationDir)) {
            error_log("FleekDash: Failed to create directory: {$integrationDir}");
            return false;
        }

        // Download and extract
        $tempFile = download_url($downloadUrl);

        if (is_wp_error($tempFile)) {
            error_log('FleekDash: Download failed: ' . $tempFile->get_error_message());
            return false;
        }

        // Extract zip
        $unzipResult = unzip_file($tempFile, $integrationDir);
        unlink($tempFile);

        if (is_wp_error($unzipResult)) {
            error_log('FleekDash: Extraction failed: ' . $unzipResult->get_error_message());
            return false;
        }

        // Verify installation
        $configFile = $integrationDir . '/config.json';
        if (!file_exists($configFile)) {
            error_log('FleekDash: Invalid integration package - missing config.json');
            $this->removeDirectory($integrationDir);
            return false;
        }

        // Run installation hooks
        $this->runInstallationHooks($integrationId, $integrationDir);

        // Clear cache
        delete_transient($this->cacheKey);

        return true;
    }

    /**
     * Uninstall integration
     */
    public function uninstallIntegration(string $integrationId): bool
    {
        $integrationDir = $this->muPluginsPath . '/fleekdash-integration-' . $integrationId;

        if (!is_dir($integrationDir)) {
            return false;
        }

        // Run uninstallation hooks
        $this->runUninstallationHooks($integrationId, $integrationDir);

        // Remove directory
        return $this->removeDirectory($integrationDir);
    }

    /**
     * Activate integration
     */
    public function activateIntegration(string $integrationId): bool
    {
        $activeIntegrations = get_option('fleekdash_active_integrations', []);
        $activeIntegrations = is_array($activeIntegrations) ? $activeIntegrations : [];

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

        // Create core loader if needed
        $this->ensureCoreLoaderExists();

        do_action('fleekdash_integration_activated', $integrationId);

        return true;
    }

    /**
     * Deactivate integration
     */
    public function deactivateIntegration(string $integrationId): bool
    {
        $activeIntegrations = get_option('fleekdash_active_integrations', []);
        $activeIntegrations = is_array($activeIntegrations) ? $activeIntegrations : [];
        $activeIntegrations = array_diff($activeIntegrations, [$integrationId]);

        update_option('fleekdash_active_integrations', $activeIntegrations);

        do_action('fleekdash_integration_deactivated', $integrationId);

        return true;
    }

    /**
     * Check if integration is active
     */
    private function isIntegrationActive(string $integrationId): bool
    {
        $activeIntegrations = get_option('fleekdash_active_integrations', []);
        $activeIntegrations = is_array($activeIntegrations) ? $activeIntegrations : [];
        return in_array($integrationId, $activeIntegrations);
    }

    /**
     * Find entry file for integration
     */
    private function findEntryFile(string $dir): ?string
    {
        $possibleFiles = [
            'fleekdash-' . basename($dir) . '.php',
            'integration.php',
            'main.php',
            'index.php'
        ];

        foreach ($possibleFiles as $file) {
            $fullPath = $dir . '/' . $file;
            if (file_exists($fullPath)) {
                return $file;
            }
        }

        return null;
    }

    /**
     * Run installation hooks
     */
    private function runInstallationHooks(string $integrationId, string $integrationDir): void
    {
        $integrationFile = $integrationDir . '/Integration.php';

        if (file_exists($integrationFile)) {
            require_once $integrationFile;

            $className = $this->getIntegrationClassName($integrationId);

            if (class_exists($className) && method_exists($className, 'install')) {
                $instance = new $className($integrationDir);
                $instance->install();
            }
        }

        do_action('fleekdash_integration_installed', $integrationId);
    }

    /**
     * Run uninstallation hooks
     */
    private function runUninstallationHooks(string $integrationId, string $integrationDir): void
    {
        $integrationFile = $integrationDir . '/Integration.php';

        if (file_exists($integrationFile)) {
            require_once $integrationFile;

            $className = $this->getIntegrationClassName($integrationId);

            if (class_exists($className) && method_exists($className, 'uninstall')) {
                $instance = new $className($integrationDir);
                $instance->uninstall();
            }
        }

        do_action('fleekdash_integration_uninstalled', $integrationId);
    }

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

    /**
     * Remove directory recursively
     */
    private function removeDirectory(string $dir): bool
    {
        if (!is_dir($dir)) {
            return false;
        }

        $files = array_diff(scandir($dir), ['.', '..']);

        foreach ($files as $file) {
            $path = $dir . '/' . $file;
            is_dir($path) ? $this->removeDirectory($path) : unlink($path);
        }

        return rmdir($dir);
    }

    /**
     * Ensure core loader exists in mu-plugins
     */
    private function ensureCoreLoaderExists(): void
    {
        $loaderFile = $this->muPluginsPath . '/fleekdash-core.php';

        if (!file_exists($loaderFile)) {
            $this->createCoreLoader($loaderFile);
        }
    }

    /**
     * Create core loader file
     */
    private function createCoreLoader(string $loaderFile): void
    {
        $content = <<<PHP
<?php
/**
 * FleekDash Core MU Plugin Loader
 *
 * Automatically loads and manages FleekDash integrations
 * Auto-generated: {date('Y-m-d H:i:s')}
 */

defined('ABSPATH') || exit;

// Only run if FleekDash is active
if (!is_plugin_active('fleekdash/fleekdash.php')) {
    return;
}

/**
 * Load active FleekDash integrations
 */
function fleekdash_load_mu_integrations() {
    \$activeIntegrations = get_option('fleekdash_active_integrations', []);
    \$muPluginsDir = WP_CONTENT_DIR . '/mu-plugins';

    foreach (\$activeIntegrations as \$integrationId) {
        \$integrationDir = \$muPluginsDir . '/fleekdash-integration-' . \$integrationId;
        \$entryFile = \$integrationDir . '/fleekdash-' . \$integrationId . '.php';

        if (file_exists(\$entryFile)) {
            require_once \$entryFile;
        }
    }
}

// Load integrations early
add_action('muplugins_loaded', 'fleekdash_load_mu_integrations', 1);

PHP;

        file_put_contents($loaderFile, $content);
    }

    /**
     * Get integration statistics
     */
    public function getStats(): array
    {
        $integrations = $this->discoverIntegrations();

        $stats = [
            'total' => count($integrations),
            'installed' => 0,
            'active' => 0,
            'available' => 0,
            'updates' => 0,
            'by_category' => []
        ];

        foreach ($integrations as $integration) {
            if ($integration['type'] === 'local') {
                $stats['installed']++;
            } else {
                $stats['available']++;
            }

            if ($integration['active']) {
                $stats['active']++;
            }

            if (isset($integration['update_available'])) {
                $stats['updates']++;
            }

            $category = $integration['category'];
            $stats['by_category'][$category] = ($stats['by_category'][$category] ?? 0) + 1;
        }

        return $stats;
    }
}
