<?php

declare(strict_types=1);

final class MyronModuleLoader
{
    /**
     * @param list<string> $moduleSlugs
     */
    public static function load(MyronModuleRegistry $registry, string $appRoot, array $moduleSlugs = []): void
    {
        $modulesRoot = rtrim($appRoot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'modules';
        if ($moduleSlugs === []) {
            $moduleSlugs = self::discoverModuleSlugs($modulesRoot);
        }

        foreach ($moduleSlugs as $slug) {
            $slug = trim($slug, " \t\n\r\0\x0B/");
            if ($slug === '') {
                continue;
            }

            $moduleFile = $modulesRoot . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $slug) . DIRECTORY_SEPARATOR . 'module.php';
            if (!is_file($moduleFile)) {
                continue;
            }
            if (!self::canRecognizeModule($slug)) {
                continue;
            }

            $manifest = require $moduleFile;
            if (is_callable($manifest)) {
                $registry->markPresent($slug);
                $manifest($registry, $appRoot);
            }
        }
    }

    private static function canRecognizeModule(string $slug): bool
    {
        $sku = self::paidSkuForSlug($slug);
        if ($sku === '') {
            return true;
        }

        if (!function_exists('myronLicenseRepository') || !function_exists('myronModulePackageInstallLedger')) {
            return true;
        }

        try {
            $snapshot = myronLicenseRepository()->currentSnapshot();
            if (!$snapshot instanceof MyronEntitlementSnapshot || $snapshot->status !== MyronLicenseStatus::ACTIVE) {
                return false;
            }
            $active = false;
            foreach ($snapshot->activeSkus as $activeSku) {
                if ((string) ($activeSku['id'] ?? '') === $sku) {
                    $active = true;
                    break;
                }
            }
            if (!$active) {
                return false;
            }

            return myronModulePackageInstallLedger()->hasTrustedInstallForSlug($slug, $sku);
        } catch (Throwable) {
            return false;
        }
    }

    private static function paidSkuForSlug(string $slug): string
    {
        return match (trim($slug, '/')) {
            'byok_ai' => 'pro-byok-ai',
            'commerce' => 'pro-commerce',
            'content/personal_pages', 'content/vcards', 'funnels', 'quizzes' => 'pro-funnels',
            'devops' => 'pro-devops',
            'lms' => 'pro-lms',
            default => '',
        };
    }

    /**
     * @return list<string>
     */
    private static function discoverModuleSlugs(string $modulesRoot): array
    {
        if (!is_dir($modulesRoot)) {
            return [];
        }

        $slugs = [];
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($modulesRoot, FilesystemIterator::SKIP_DOTS)
        );

        foreach ($iterator as $fileInfo) {
            if (!$fileInfo instanceof SplFileInfo || !$fileInfo->isFile() || $fileInfo->getFilename() !== 'module.php') {
                continue;
            }

            $directory = $fileInfo->getPath();
            $relative = ltrim(substr($directory, strlen($modulesRoot)), DIRECTORY_SEPARATOR);
            if ($relative !== '') {
                $slugs[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative);
            }
        }

        sort($slugs);
        return array_values(array_unique($slugs));
    }
}
