<?php

declare(strict_types=1);

namespace apexl\Io\modules\system\Factories;

use apexl\Config\Configuration;
use apexl\Config\Exceptions\InvalidConfigException;
use apexl\Io\includes\Utils;
use apexl\Io\services\FilePaths;
use apexl\Utils\Paths\Globstar;

final readonly class ConfigurationFactory
{
    /**
     * @param array<string> $exclude
     */
    public function __construct(private FilePaths $filePaths, private array $exclude = []) {}

    /**
     * @throws InvalidConfigException
     */
    public function make(): Configuration
    {
        $config = new Configuration();

        $configFiles = $this->findConfigFiles();

        foreach ($configFiles as $file) {
            if (in_array(basename($file), $this->exclude)) {
                continue;
            }

            $config->load(
                file: $file,
                options: [
                    'lock' => false
                ]
            );
        }

        return $config;
    }

    private function findConfigFiles()
    {
        $configDirectories = $this->findConfigDirectories();

        return array_reduce($configDirectories, function (array $carry, string $configDirectory): array {
            return [
                ...$carry,
                ...$this->findFilesInDirectory($configDirectory)
            ];
        }, []);
    }

    private function findConfigDirectories(): array
    {
        $configDirectories = $this->findModuleConfigDirectories();

        $appConfigDirectory = $this->filePaths->configDir();

        if (file_exists($appConfigDirectory)) {
            $configDirectories[] = $appConfigDirectory;
        }

        return $configDirectories;
    }

    private function findModuleConfigDirectories(): array
    {
        return Globstar::globstar(
            $this->filePaths->basePath('vendor/apexl/*/**/config'),
        );
    }

    private function findFilesInDirectory(string $configDirectory): array
    {
        $files = Utils::getFilesInDirectory($configDirectory, ['php'], ['.local.php', '.example.php']);
        ksort($files, SORT_NATURAL);

        return $files;

    }


}