<?php
declare(strict_types=1);

require_once __DIR__ . '/hooks.php';

if (!function_exists('cms_plugin_headers')) {
    function cms_plugin_headers(): array
    {
        return [
            'Plugin Name' => 'name',
            'Plugin Slug' => 'declared_slug',
            'Description' => 'description',
            'Version' => 'version',
        ];
    }
}

if (!function_exists('plugin_bootstrap_candidates')) {
    function plugin_bootstrap_candidates(string $pluginDir, string $pluginName): array
    {
        return [
            $pluginDir . '/plugin.php',
            $pluginDir . '/main.php',
            $pluginDir . '/index.php',
            $pluginDir . '/bootstrap.php',
            $pluginDir . '/' . $pluginName . '.php',
        ];
    }
}

if (!function_exists('plugin_bootstrap_file')) {
    function plugin_bootstrap_file(string $pluginDir, string $pluginName): ?string
    {
        foreach (plugin_bootstrap_candidates($pluginDir, $pluginName) as $bootstrapFile) {
            if (is_file($bootstrapFile)) {
                return $bootstrapFile;
            }
        }

        $phpFiles = glob($pluginDir . '/*.php');
        if ($phpFiles !== false && count($phpFiles) === 1) {
            return $phpFiles[0];
        }

        return null;
    }
}

if (!function_exists('plugin_parse_metadata')) {
    function plugin_parse_metadata(string $bootstrapFile, string $pluginSlug): array
    {
        $metadata = [
            'slug' => $pluginSlug,
            'declared_slug' => $pluginSlug,
            'name' => ucwords(str_replace(['-', '_'], ' ', $pluginSlug)),
            'description' => '',
            'version' => '1.0',
            'bootstrap' => $bootstrapFile,
            'active' => false,
            'status' => 'inactive',
            'error' => '',
            'blocks' => [],
        ];

        $contents = (string) @file_get_contents($bootstrapFile);
        if ($contents === '') {
            return $metadata;
        }

        if (preg_match('#/\*(.*?)\*/#s', $contents, $matches)) {
            $headerBlock = $matches[1];
            foreach (cms_plugin_headers() as $headerLabel => $targetKey) {
                if (preg_match('/^\s*' . preg_quote($headerLabel, '/') . ':\s*(.+)$/mi', $headerBlock, $headerMatch)) {
                    $metadata[$targetKey] = trim($headerMatch[1]);
                }
            }
        }

        $metadata['declared_slug'] = preg_match('/^[a-z0-9_-]+$/i', (string) $metadata['declared_slug'])
            ? strtolower((string) $metadata['declared_slug'])
            : $pluginSlug;
        $metadata['blocks'] = function_exists('plugin_declared_blocks') ? plugin_declared_blocks($bootstrapFile) : [];

        return $metadata;
    }
}

if (!function_exists('plugin_declared_blocks')) {
    function plugin_declared_blocks(string $bootstrapFile): array
    {
        $contents = (string) @file_get_contents($bootstrapFile);
        if ($contents === '') {
            return [];
        }

        preg_match_all('/register_block\(\s*[\'"]([^\'"]+)[\'"]\s*,/i', $contents, $matches);
        if (empty($matches[1]) || !is_array($matches[1])) {
            return [];
        }

        return array_values(array_unique(array_filter(array_map(static function ($block): string {
            return strtolower(trim((string) $block));
        }, $matches[1]))));
    }
}

if (!function_exists('cms_get_plugins')) {
    function cms_get_plugins(string $pluginsRoot, array $activePlugins = []): array
    {
        $plugins = [];

        if (!is_dir($pluginsRoot)) {
            return $plugins;
        }

        $pluginDirs = glob($pluginsRoot . '/*', GLOB_ONLYDIR);
        if ($pluginDirs === false) {
            return $plugins;
        }

        sort($pluginDirs);

        foreach ($pluginDirs as $pluginDir) {
            $pluginName = basename($pluginDir);
            $bootstrapFile = plugin_bootstrap_file($pluginDir, $pluginName);
            if ($bootstrapFile === null) {
                continue;
            }

            $plugin = plugin_parse_metadata($bootstrapFile, $pluginName);
            $plugin['active'] = in_array($pluginName, $activePlugins, true);
            $plugin['status'] = $plugin['active'] ? 'active' : 'inactive';
            $plugins[$pluginName] = $plugin;
        }

        return $plugins;
    }
}

if (!function_exists('cms_discover_plugin_slugs')) {
    function cms_discover_plugin_slugs(?string $rootPath = null): array
    {
        $basePath = $rootPath ?: (defined('CMS_ROOT') ? CMS_ROOT : dirname(__DIR__));
        $plugins = cms_get_plugins(rtrim($basePath, '/\\') . '/content/plugins');

        return array_keys($plugins);
    }
}

if (!function_exists('plugin_safe_include')) {
    function plugin_safe_include(string $pluginSlug, string $bootstrapFile): array
    {
        $capturedOutput = '';
        $errorMessage = '';

        try {
            ob_start();
            require_once $bootstrapFile;
            $capturedOutput = ob_get_clean();
        } catch (Throwable $exception) {
            if (ob_get_level() > 0) {
                ob_end_clean();
            }
            $errorMessage = $exception->getMessage();
        }

        return [
            'output' => $capturedOutput,
            'error' => $errorMessage,
        ];
    }
}

if (!function_exists('load_plugins')) {
    function load_plugins(string $pluginsRoot, array $activePlugins = []): array
    {
        $allPlugins = cms_get_plugins($pluginsRoot, $activePlugins);
        $pluginRegistry = $allPlugins;
        $loadedPlugins = [];
        $pluginBootstrapOutput = [];
        $pluginErrors = [];

        $activePlugins = array_values(array_unique(array_filter(array_map(static function ($plugin): string {
            return strtolower(trim((string) $plugin));
        }, $activePlugins))));

        foreach ($activePlugins as $pluginSlug) {
            if (!isset($allPlugins[$pluginSlug])) {
                $pluginErrors[$pluginSlug] = 'Plugin not found or missing bootstrap file.';
                continue;
            }

            $plugin = $allPlugins[$pluginSlug];
            $bootstrapFile = (string) ($plugin['bootstrap'] ?? '');

            if ($bootstrapFile === '' || !is_file($bootstrapFile)) {
                $pluginRegistry[$pluginSlug]['status'] = 'error';
                $pluginRegistry[$pluginSlug]['error'] = 'Plugin bootstrap file is missing.';
                $pluginErrors[$pluginSlug] = 'Plugin bootstrap file is missing.';
                continue;
            }

            error_log('[CMS Plugin Loader] Loading plugin: ' . $pluginSlug);

            $result = plugin_safe_include($pluginSlug, $bootstrapFile);
            if ($result['output'] !== '') {
                $pluginBootstrapOutput[$pluginSlug] = $result['output'];
            }

            if ($result['error'] !== '') {
                $pluginRegistry[$pluginSlug]['status'] = 'error';
                $pluginRegistry[$pluginSlug]['error'] = $result['error'];
                $pluginErrors[$pluginSlug] = $result['error'];
                continue;
            }

            $pluginRegistry[$pluginSlug]['status'] = 'loaded';
            $loadedPlugins[$pluginSlug] = (string) $plugin['bootstrap'];
        }

        $GLOBALS['plugins_registry'] = $pluginRegistry;
        $GLOBALS['loaded_plugins'] = $loadedPlugins;
        $GLOBALS['plugin_bootstrap_output'] = $pluginBootstrapOutput;
        $GLOBALS['plugin_errors'] = $pluginErrors;

        return $loadedPlugins;
    }
}
