<?php

namespace Silvanus\includes\blocks;

use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use FilesystemIterator;

final class BlockModules
{
    public static function registerAll(): void
    {


        $parentBlocks = realpath(get_template_directory() . '/blocks') ?: '';
        $childBlocks = realpath(get_stylesheet_directory() . '/blocks') ?: '';

        $baseDirs = [
            $parentBlocks,
            $childBlocks,
        ];

        $moduleFiles = [];

        foreach ($baseDirs as $baseDir) {
            if (!is_dir($baseDir) || !is_readable($baseDir)) {
                continue;
            }

            $baseReal = realpath($baseDir);
            if (!$baseReal) {
                continue;
            }

            $iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($baseReal, FilesystemIterator::SKIP_DOTS),
                RecursiveIteratorIterator::LEAVES_ONLY,
            );

            foreach ($iterator as $fileInfo) {
                if (!$fileInfo->isFile()) {
                    continue;
                }

                $filename = $fileInfo->getFilename();
                if (!str_ends_with($filename, '.block.php')) {
                    continue;
                }

                $realFile = $fileInfo->getRealPath();
                if (!$realFile || str_starts_with($realFile, $baseReal) === false) {
                    continue;
                }

                $relative = ltrim(str_replace($baseReal, '', $realFile), '\\/');

                if (!isset($moduleFiles[$relative])) {
                    $moduleFiles[$relative] = $realFile;
                }
            }
        }

        if (empty($moduleFiles)) {
            return;
        }

        foreach ($moduleFiles as $realFile) {
            $realDir = dirname($realFile);

            // Choose correct base path safely (child only if it exists and matches)
            $baseReal = null;

            if ($childBlocks !== '' && str_starts_with($realFile, $childBlocks)) {
                $baseReal = $childBlocks;
            } elseif ($parentBlocks !== '' && str_starts_with($realFile, $parentBlocks)) {
                $baseReal = $parentBlocks;
            } else {
                continue;
            }

            $relativeDir = trim(str_replace($baseReal, '', $realDir), '\\/');

            if ($relativeDir === '') {
                continue;
            }

            $parts = preg_split('#[\\\\/]#', $relativeDir) ?: [];
            $parts = array_values(array_filter($parts, static fn($p) => is_string($p) && $p !== ''));

            $namespaceParts = array_map([self::class, 'studlyFromSlug'], $parts);
            $namespaceParts[0] = $parts[0]; // keep top folder lower-case

            $classBase = 'Silvanus\\blocks\\' . implode('\\', $namespaceParts) . '\\Module';

            require_once $realFile;

            if (!class_exists($classBase) || !is_subclass_of($classBase, BlockModuleInterface::class)) {
                continue;
            }

            (new $classBase())->register();
        }
    }

    private static function studlyFromSlug(string $slug): string
    {
        return str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $slug)));
    }
}