<?php
class ModuleRegistry
{
    private static ?array $modules = null;

    public static function getModules(): array
    {
        self::loadIfNeeded();
        return self::$modules;
    }

    public static function getModule(string $name): ?array
    {
        self::loadIfNeeded();
        return self::$modules[$name] ?? null;
    }

    public static function getMenuItems(): array
    {
        $items = [];
        foreach (self::getModules() as $mod) {
            if (isset($mod['menu'])) {
                foreach ($mod['menu'] as $menuItem) {
                    $menuItem['_module'] = $mod['name'];
                    $menuItem['_sort'] = $menuItem['sort_order'] ?? $mod['sort_order'] ?? 100;
                    $items[] = $menuItem;
                }
            }
        }
        usort($items, fn($a, $b) => ($a['_sort'] ?? 100) <=> ($b['_sort'] ?? 100));
        return $items;
    }

    public static function getRoutes(): array
    {
        $allRoutes = [];
        foreach (self::getModules() as $mod) {
            $routesFile = ROOT_PATH . '/modules/' . $mod['name'] . '/' . ($mod['routes_file'] ?? 'routes.php');
            if (file_exists($routesFile)) {
                $routes = require $routesFile;
                if (is_array($routes)) {
                    foreach ($routes as $route) {
                        $route['_module'] = $mod['name'];
                        $allRoutes[] = $route;
                    }
                }
            }
        }
        return $allRoutes;
    }

    public static function getWidgets(): array
    {
        $widgets = [];
        foreach (self::getModules() as $mod) {
            if (isset($mod['dashboard_widgets'])) {
                foreach ($mod['dashboard_widgets'] as $widget) {
                    $widget['_module'] = $mod['name'];
                    $widgets[] = $widget;
                }
            }
        }
        usort($widgets, fn($a, $b) => ($a['sort_order'] ?? 100) <=> ($b['sort_order'] ?? 100));
        return $widgets;
    }

    public static function getCssFiles(): array
    {
        $files = [];
        foreach (self::getModules() as $mod) {
            if (isset($mod['css_files'])) {
                foreach ($mod['css_files'] as $css) {
                    $fullPath = '/modules/' . $mod['name'] . '/' . $css;
                    if (file_exists(ROOT_PATH . $fullPath) || file_exists(PUBLIC_PATH . '/modules/' . $mod['name'] . '/' . $css)) {
                        $files[] = $fullPath;
                    }
                }
            }
        }
        return $files;
    }

    public static function getJsFiles(): array
    {
        $files = [];
        foreach (self::getModules() as $mod) {
            if (isset($mod['js_files'])) {
                foreach ($mod['js_files'] as $js) {
                    $fullPath = '/modules/' . $mod['name'] . '/' . $js;
                    $files[] = $fullPath;
                }
            }
        }
        return $files;
    }

    private static function loadIfNeeded(): void
    {
        if (self::$modules !== null) return;
        self::$modules = [];

        $modulesPath = ROOT_PATH . '/modules';
        if (!is_dir($modulesPath)) {
            @mkdir($modulesPath, 0755, true);
            return;
        }

        foreach (scandir($modulesPath) as $dir) {
            if ($dir === '.' || $dir === '..') continue;
            $manifestFile = $modulesPath . '/' . $dir . '/module.json';
            if (file_exists($manifestFile)) {
                $manifest = json_decode(file_get_contents($manifestFile), true);
                if ($manifest && isset($manifest['name'])) {
                    self::$modules[$manifest['name']] = $manifest;
                }
            }
        }

        uasort(self::$modules, fn($a, $b) => ($a['sort_order'] ?? 100) <=> ($b['sort_order'] ?? 100));
    }

    public static function clearCache(): void
    {
        self::$modules = null;
    }
}