<?php

declare(strict_types=1);

namespace Flowaxy\Bootstrap;

use Flowaxy\Core\System\PathResolver;
use Flowaxy\Infrastructure\Config\Config;
use Flowaxy\Support\Helpers\IniHelper;
use Flowaxy\Support\Helpers\JsonHelper;

use function addslashes;
use function chmod;
use function class_exists;
use function defined;
use function dirname;
use function file_exists;
use function file_put_contents;
use function is_array;
use function is_dir;
use function is_string;
use function mkdir;
use function pathinfo;
use function str_contains;
use function password_hash;
use const DIRECTORY_SEPARATOR;
use const DS;
use const PASSWORD_DEFAULT;

// Ініціалізатор конфігурації системи
final class ConfigurationInitializer
{
    // Ініціалізація конфігурації: завантаження БД та визначення констант
    public static function initialize(string $protocol, string $host): void
    {
        ConfigLoader::loadDatabaseConfig();

        // Инициализируем Config для автоматического создания остальных конфигурационных файлов
        self::ensureConfigFiles();

        ConstantsDefiner::define($protocol, $host);
    }

    /**
     * Обеспечиваем создание всех необходимых конфигурационных файлов и директорий
     *
     * @return void
     */
    private static function ensureConfigFiles(): void
    {
        if (!class_exists(PathResolver::class)) {
            return;
        }

        // Инициализируем Config, чтобы создать базовую директорию и поддиректории
        // Config::getInstance() автоматически создаст storage/config и поддиректории (plugins, system, themes)
        if (class_exists(Config::class)) {
            try {
                Config::getInstance();
            } catch (\Throwable $e) {
                // Игнорируем ошибки инициализации Config
            }
        }

        $configDir = PathResolver::storageConfig();
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;

        // Список системных конфигурационных файлов в storage/config/system/
        // database.ini НЕ створюється автоматично (налаштовується з адмінки)
        $systemConfigFiles = [
            'app.ini',
            'cache.ini',
            // 'feature-flags.ini' - удалено, дефолтные значения хардкодные в FeatureFlagManager
            // 'modules.ini' - удалено, используется система плагинов, а не модулей
            'security.ini',
            'logging.ini', // Для настроек логирования
        ];

        // Создаем системные конфигурационные файлы в storage/config/system/
        $systemDir = $configDir . $ds . 'system';

        // Убеждаемся, что директория system существует
        if (!is_dir($systemDir)) {
            if (!@mkdir($systemDir, 0755, true) && !is_dir($systemDir)) {
                error_log("ConfigurationInitializer: Failed to create system config directory: {$systemDir}");
                return;
            }
        }

        foreach ($systemConfigFiles as $configFile) {
            $configName = pathinfo($configFile, PATHINFO_FILENAME);
            $filePath = $systemDir . $ds . $configFile;

            if (!file_exists($filePath)) {
                // Пытаемся создать файл через Config
                $created = false;
                if (class_exists(Config::class)) {
                    try {
                        $config = Config::getInstance();
                        $created = $config->ensureConfig($configName, '.ini');
                    } catch (\Throwable $e) {
                        // Логируем ошибку, но продолжаем попытку прямого создания
                        error_log("ConfigurationInitializer: Config::ensureConfig failed for '{$configName}': " . $e->getMessage());
                    }
                }

                // Если файл все еще не создан, создаем напрямую
                if (!$created && !file_exists($filePath)) {
                    try {
                        $defaultData = self::getDefaultConfigData($configName);

                        // Проверяем, есть ли дефолтные данные
                        $hasData = !empty($defaultData);

                        if ($hasData) {
                            // Создаем файл напрямую через IniHelper
                            if (class_exists(IniHelper::class)) {
                                $created = IniHelper::writeFile($filePath, $defaultData, true);
                            } else {
                                // Fallback: создаем файл напрямую через file_put_contents
                                $iniContent = self::generateIniContent($defaultData);
                                $created = @file_put_contents($filePath, $iniContent) !== false;
                            }

                            if ($created && file_exists($filePath)) {
                                @chmod($filePath, 0644);
                            } else {
                                error_log("ConfigurationInitializer: Failed to create config file directly: {$filePath}");
                            }
                        } else {
                            error_log("ConfigurationInitializer: No default data for config '{$configName}', skipping file creation");
                        }
                    } catch (\Throwable $e) {
                        error_log("ConfigurationInitializer: Error creating config file '{$configName}' directly: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
                    }
                }
            }
        }

        // Создаем installed.flag автоматически при первом запуске
        self::ensureInstalledFlag();

        // Создаем конфигурацию сервисов DI контейнера в storage/config/flowaxy/services.json
        self::ensureServicesConfig();

        // Создаем конфигурацию root пользователя
        self::ensureRootUserConfig();

        // Создаем конфигурацию плагинов и тем
        self::ensurePluginsThemesConfig();

        // Создаем все необходимые storage директории с .htaccess файлами
        self::ensureStorageDirectories();

        // Создаем корневой .htaccess файл
        self::ensureRootHtaccess();

        // Создаем папку uploads с .htaccess файлом
        self::ensureUploadsDirectory();
    }

    /**
     * Получение дефолтных значений для конфигурационного файла
     * Дублируем логику из Config для прямого создания файлов
     *
     * @param string $configName Имя конфигурации
     * @return array<string, mixed> Дефолтные значения
     */
    private static function getDefaultConfigData(string $configName): array
    {
        return match ($configName) {
            'app' => [
                'app' => [
                    'name' => 'Flowaxy CMS',
                    'version' => '1.0.0',
                    'environment' => 'production',
                    'debug' => '0',
                    'maintenance_mode' => '0',
                    'timezone' => '',
                    'locale' => 'uk',
                    'charset' => 'UTF-8',
                    'site_name' => 'My Site',
                ],
                'url' => [
                    'url' => 'http://localhost',
                    'asset_url' => '',
                ],
                'performance' => [
                    'enable_query_cache' => '1',
                    'enable_opcache' => '1',
                ],
            ],
            'cache' => [
                'cache' => [
                    'enabled' => '0',
                    'default_ttl' => '3600',
                    'auto_cleanup' => '1',
                    'driver' => 'file',
                ],
            ],
            // 'feature-flags' - удалено, дефолтные значения хардкодные в FeatureFlagManager
            // 'modules' - удалено, используется система плагинов, а не модулей
            'security' => [
                'security' => [
                    'session_lifetime' => '7200',
                    'cookie_lifetime' => '86400',
                    'cookie_path' => '/',
                    'cookie_domain' => '',
                    'cookie_httponly' => '1',
                    'cookie_secure' => '0',
                ],
                'command_whitelist' => [],
            ],
            'logging' => [
                'logging' => [
                    'enabled' => '1',
                    'levels' => 'DEBUG,INFO,WARNING,ERROR,CRITICAL',
                    'types' => 'file,db_queries,db_errors,slow_queries',
                    'max_file_size' => '10485760',
                    'retention_days' => '30',
                    'rotation_type' => 'size',
                    'rotation_time' => '24',
                    'rotation_time_unit' => 'hours',
                ],
            ],
            default => [],
        };
    }

    /**
     * Генерация INI контента из массива данных (fallback)
     *
     * @param array<string, mixed> $data Данные конфигурации
     * @return string INI контент
     */
    private static function generateIniContent(array $data): string
    {
        $output = '';
        $output .= "; Auto-generated by Flowaxy CLI\n";
        $output .= "; Do not edit manually if you're not sure\n\n";

        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $output .= "[{$key}]\n";
                foreach ($value as $subKey => $subValue) {
                    if (is_array($subValue)) {
                        // Вложенные массивы не поддерживаются в INI, пропускаем
                        continue;
                    }
                    $formattedValue = self::formatIniValue($subValue);
                    $output .= "{$subKey} = {$formattedValue}\n";
                }
                $output .= "\n";
            } else {
                $formattedValue = self::formatIniValue($value);
                $output .= "{$key} = {$formattedValue}\n";
            }
        }

        return $output;
    }

    /**
     * Форматирование значения для INI
     *
     * @param mixed $value Значение
     * @return string Отформатированное значение
     */
    private static function formatIniValue(mixed $value): string
    {
        if (is_bool($value)) {
            return $value ? '1' : '0';
        }
        $stringValue = (string)$value;
        // Хеши паролей и другие длинные строки с спецсимволами должны быть в кавычках
        if (is_string($value) && (
            str_contains($stringValue, ' ') ||
            str_contains($stringValue, '=') ||
            str_contains($stringValue, ';') ||
            str_contains($stringValue, '$') ||
            str_contains($stringValue, '"') ||
            str_contains($stringValue, "\n") ||
            str_contains($stringValue, "\r")
        )) {
            return '"' . addslashes($stringValue) . '"';
        }
        return $stringValue;
    }

    /**
     * Создание конфигурации сервисов DI контейнера в storage/config/flowaxy/services.json
     *
     * @return void
     */
    private static function ensureServicesConfig(): void
    {
        if (!class_exists(PathResolver::class)) {
            return;
        }

        $configDir = PathResolver::storageConfig();
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        $flowaxyDir = $configDir . $ds . 'flowaxy';
        $servicesJsonFile = $flowaxyDir . $ds . 'services.json';

        // Если файл уже существует, не перезаписываем его
        if (file_exists($servicesJsonFile)) {
            return;
        }

        // Создаем директорию flowaxy, если её нет
        if (!is_dir($flowaxyDir)) {
            if (!@mkdir($flowaxyDir, 0755, true) && !is_dir($flowaxyDir)) {
                error_log("ConfigurationInitializer: Failed to create flowaxy config directory: {$flowaxyDir}");
                return;
            }
        }

        // Дефолтная конфигурация сервисов
        $defaultServicesConfig = [
            'singletons' => [
                // Theme services
                'ThemeRepositoryInterface' => 'ThemeRepository',
                'ThemeSettingsRepositoryInterface' => 'ThemeSettingsRepository',
                'ActivateThemeService' => 'ActivateThemeService',
                'UpdateThemeSettingsService' => 'UpdateThemeSettingsService',

                // Plugin services
                'PluginRepositoryInterface' => 'PluginRepository',
                'PluginFilesystemInterface' => 'PluginFilesystem',
                'PluginCacheInterface' => 'PluginCacheManager',
                'InstallPluginService' => 'InstallPluginService',
                'ActivatePluginService' => 'ActivatePluginService',
                'DeactivatePluginService' => 'DeactivatePluginService',
                'TogglePluginService' => 'TogglePluginService',
                'UninstallPluginService' => 'UninstallPluginService',
                'PluginLifecycleInterface' => 'PluginLifecycleService',

                // Auth services
                'UserRepositoryInterface' => 'UserRepository',
                'RoleRepositoryInterface' => 'RoleRepository',
                'AuthenticateUserService' => 'AuthenticateUserService',
                'AuthorizationService' => 'AuthorizationService',
                'LogoutUserService' => 'LogoutUserService',

                // Repository contracts
                'Flowaxy\\Contracts\\Repository\\RepositoryInterface' => 'Flowaxy\\Infrastructure\\Persistence\\Repositories\\BaseRepository',
                'Flowaxy\\Contracts\\Repository\\CriteriaInterface' => 'Flowaxy\\Infrastructure\\Persistence\\Repositories\\Criteria',

                // Service contracts
                'Flowaxy\\Contracts\\Service\\ServiceInterface' => 'Flowaxy\\Core\\Services\\BaseService',
                'Flowaxy\\Contracts\\Service\\LifecycleInterface' => 'Flowaxy\\Core\\Services\\BaseService',

                // Security contracts
                'Flowaxy\\Contracts\\Security\\GuardInterface' => 'Flowaxy\\Infrastructure\\Security\\Guard',
                'Flowaxy\\Contracts\\Security\\AuthorizerInterface' => 'Flowaxy\\Infrastructure\\Security\\Authorizer',
                'Flowaxy\\Contracts\\Security\\EncryptionInterface' => 'Flowaxy\\Infrastructure\\Security\\Encryption',
                'Flowaxy\\Contracts\\Security\\HashInterface' => 'Flowaxy\\Infrastructure\\Security\\Hash',
                'Flowaxy\\Contracts\\Security\\RateLimiterInterface' => 'Flowaxy\\Infrastructure\\Security\\RateLimiter',

                // Cache contracts
                'Flowaxy\\Contracts\\Cache\\CacheInterface' => 'Flowaxy\\Infrastructure\\Cache\\Cache',

                // Database contracts
                'Flowaxy\\Contracts\\Database\\QueryBuilderInterface' => 'Flowaxy\\Infrastructure\\Persistence\\Database\\QueryBuilder',

                // Filesystem contracts
                'Flowaxy\\Contracts\\Filesystem\\FileInterface' => 'Flowaxy\\Infrastructure\\Filesystem\\File',
                'Flowaxy\\Contracts\\Filesystem\\ImageInterface' => 'Flowaxy\\Infrastructure\\Filesystem\\Image',
                'Flowaxy\\Contracts\\Filesystem\\UploadInterface' => 'Flowaxy\\Infrastructure\\Filesystem\\Upload',
                'Flowaxy\\Contracts\\Filesystem\\ArchiveInterface' => 'Flowaxy\\Infrastructure\\Filesystem\\Archive\\Zip',
                'Flowaxy\\Contracts\\Filesystem\\DirectoryInterface' => 'Flowaxy\\Infrastructure\\Filesystem\\Directory',

                // Assets contracts
                'Flowaxy\\Contracts\\Assets\\AssetManagerInterface' => 'Flowaxy\\Infrastructure\\Assets\\AssetManager',

                // Mail contracts
                'Flowaxy\\Contracts\\Mail\\MailerInterface' => 'Flowaxy\\Infrastructure\\Mail\\Mailer',
                'Flowaxy\\Contracts\\Mail\\MessageInterface' => 'Flowaxy\\Infrastructure\\Mail\\Message',

                // Config contracts
                'Flowaxy\\Contracts\\Config\\ConfigInterface' => 'Flowaxy\\Infrastructure\\Config\\SystemConfig',
                'Flowaxy\\Contracts\\Config\\ConfigLoaderInterface' => 'Flowaxy\\Infrastructure\\Config\\ConfigLoader',

                // Validation contracts
                'Flowaxy\\Contracts\\Validation\\ValidatorInterface' => 'Flowaxy\\Support\\Validation\\Validator',
                'Flowaxy\\Contracts\\Validation\\RuleInterface' => 'Flowaxy\\Support\\Validation\\Rules\\BaseRule',

                // HTTP contracts
                'Flowaxy\\Contracts\\Http\\RequestInterface' => 'Flowaxy\\Interface\\Http\\Request',
                'Flowaxy\\Contracts\\Http\\ResponseInterface' => 'Flowaxy\\Interface\\Http\\Response',
                'Flowaxy\\Contracts\\Http\\ControllerInterface' => 'Flowaxy\\Interface\\Http\\Controller',

                // Logging contracts
                'Flowaxy\\Contracts\\Logging\\LoggerInterface' => 'Flowaxy\\Infrastructure\\Logging\\Logger',
                'Flowaxy\\Contracts\\Logging\\LogFormatterInterface' => 'Flowaxy\\Infrastructure\\Logging\\Formatters\\BaseFormatter',

                // UI contracts
                'Flowaxy\\Contracts\\UI\\RendererInterface' => 'Flowaxy\\Interface\\UI\\Renderer',
                'Flowaxy\\Contracts\\UI\\ViewInterface' => 'Flowaxy\\Interface\\UI\\View',
            ],
            'bindings' => [
                // 'HookManagerInterface' => 'Custom\\HookManager',
            ],
        ];

        try {
            // Создаем JSON файл через JsonHelper
            if (class_exists(JsonHelper::class)) {
                $created = JsonHelper::writeFile($servicesJsonFile, $defaultServicesConfig, true);
            } else {
                // Fallback: создаем файл напрямую через file_put_contents
                $jsonContent = json_encode($defaultServicesConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
                $created = @file_put_contents($servicesJsonFile, $jsonContent) !== false;
            }

            if ($created && file_exists($servicesJsonFile)) {
                @chmod($servicesJsonFile, 0644);
            } else {
                error_log("ConfigurationInitializer: Failed to create services.json file: {$servicesJsonFile}");
            }
        } catch (\Throwable $e) {
            error_log("ConfigurationInitializer: Error creating services.json: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
        }
    }

    /**
     * Создание конфигурации root пользователя в storage/config/system/root.ini
     *
     * @return void
     */
    private static function ensureRootUserConfig(): void
    {
        if (!class_exists(PathResolver::class)) {
            return;
        }

        $configDir = PathResolver::storageConfig();
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        $systemDir = $configDir . $ds . 'system';
        $rootIniFile = $systemDir . $ds . 'root.ini';

        // Если файл уже существует, не перезаписываем его
        if (file_exists($rootIniFile)) {
            return;
        }

        // Создаем директорию system, если её нет
        if (!is_dir($systemDir)) {
            if (!@mkdir($systemDir, 0755, true) && !is_dir($systemDir)) {
                error_log("ConfigurationInitializer: Failed to create system config directory: {$systemDir}");
                return;
            }
        }

        // Дефолтная конфигурация root пользователя
        // Пароль по умолчанию: "root" (должен быть изменен при первом входе)
        // Хешируем пароль сразу при создании файла
        $defaultPassword = 'root';
        $passwordHash = '';

        // Пытаемся создать хеш пароля
        // Используем встроенную функцию PHP password_hash(), так как Hash facade может быть недоступен на раннем этапе
        if (function_exists('password_hash')) {
            try {
                $passwordHash = password_hash($defaultPassword, PASSWORD_DEFAULT);
                if (empty($passwordHash)) {
                    error_log("ConfigurationInitializer: password_hash() returned empty string for root password");
                }
            } catch (\Throwable $e) {
                // Если password_hash недоступна, оставляем пустым
                // Хеш будет создан при первом обращении через RootUserConfig::getPasswordHash()
                error_log("ConfigurationInitializer: Failed to hash root password during initialization: " . $e->getMessage());
            }
        } else {
            error_log("ConfigurationInitializer: password_hash() function not available - root password hash will be created on first access");
        }

        $defaultRootConfig = [
            'root' => [
                'username' => 'root',
                'password_hash' => $passwordHash, // Хеш создается сразу, если Hash доступен
                'email' => 'root@localhost',
                'created_at' => date('Y-m-d H:i:s'),
                'is_active' => '1',
            ],
        ];

        try {
            // Создаем INI файл через IniHelper
            if (class_exists(IniHelper::class)) {
                $created = IniHelper::writeFile($rootIniFile, $defaultRootConfig, true);
            } else {
                // Fallback: создаем файл напрямую через file_put_contents
                $iniContent = self::generateIniContent($defaultRootConfig);
                $created = @file_put_contents($rootIniFile, $iniContent) !== false;
            }

            if ($created && file_exists($rootIniFile)) {
                @chmod($rootIniFile, 0600); // Только владелец может читать/писать
            } else {
                error_log("ConfigurationInitializer: Failed to create root.ini file: {$rootIniFile}");
            }
        } catch (\Throwable $e) {
            error_log("ConfigurationInitializer: Error creating root.ini: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
        }
    }

    /**
     * Создание файла installed.flag в storage/config/system/installed.flag
     * Файл создается автоматически при первом запуске с текущей датой
     *
     * @return void
     */
    private static function ensureInstalledFlag(): void
    {
        if (!class_exists(PathResolver::class)) {
            return;
        }

        $configDir = PathResolver::storageConfig();
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        $systemDir = $configDir . $ds . 'system';
        $installedFlagFile = $systemDir . $ds . 'installed.flag';

        // Если файл уже существует, не перезаписываем его
        if (file_exists($installedFlagFile)) {
            return;
        }

        // Создаем директорию system, если её нет
        if (!is_dir($systemDir)) {
            if (!@mkdir($systemDir, 0755, true) && !is_dir($systemDir)) {
                error_log("ConfigurationInitializer: Failed to create system config directory: {$systemDir}");
                return;
            }
        }

        try {
            // Создаем файл с текущей датой и временем
            $installDate = date('Y-m-d H:i:s');
            $content = "Installed: {$installDate}\n";
            $content .= "This file indicates that Flowaxy Framework has been initialized.\n";
            $content .= "Do not delete this file unless you want to reset the installation state.\n";

            $created = @file_put_contents($installedFlagFile, $content) !== false;

            if ($created && file_exists($installedFlagFile)) {
                @chmod($installedFlagFile, 0644);
            } else {
                error_log("ConfigurationInitializer: Failed to create installed.flag file: {$installedFlagFile}");
            }
        } catch (\Throwable $e) {
            error_log("ConfigurationInitializer: Error creating installed.flag: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
        }
    }

    /**
     * Создание конфигурационных файлов для плагинов и тем
     * plugins.ini и themes.ini в storage/config/system/
     *
     * @return void
     */
    private static function ensurePluginsThemesConfig(): void
    {
        if (!class_exists(PathResolver::class)) {
            return;
        }

        $configDir = PathResolver::storageConfig();
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        $systemDir = $configDir . $ds . 'system';
        $pluginsIniFile = $systemDir . $ds . 'plugins.ini';
        $themesIniFile = $systemDir . $ds . 'themes.ini';

        // Создаем директорию system, если её нет
        if (!is_dir($systemDir)) {
            if (!@mkdir($systemDir, 0755, true) && !is_dir($systemDir)) {
                error_log("ConfigurationInitializer: Failed to create system config directory: {$systemDir}");
                return;
            }
        }

        // Создаем plugins.ini, если его нет
        if (!file_exists($pluginsIniFile)) {
            try {
                $defaultPluginsConfig = [
                    'plugins' => [
                        // Плагины будут добавляться автоматически при установке
                    ],
                ];

                if (class_exists(IniHelper::class)) {
                    $created = IniHelper::writeFile($pluginsIniFile, $defaultPluginsConfig, true);
                } else {
                    $iniContent = self::generateIniContent($defaultPluginsConfig);
                    $created = @file_put_contents($pluginsIniFile, $iniContent) !== false;
                }

                if ($created && file_exists($pluginsIniFile)) {
                    @chmod($pluginsIniFile, 0644);
                } else {
                    error_log("ConfigurationInitializer: Failed to create plugins.ini file: {$pluginsIniFile}");
                }
            } catch (\Throwable $e) {
                error_log("ConfigurationInitializer: Error creating plugins.ini: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
            }
        }

        // Создаем themes.ini, если его нет
        if (!file_exists($themesIniFile)) {
            try {
                $defaultThemesConfig = [
                    'themes' => [
                        // Темы будут добавляться автоматически при установке
                    ],
                ];

                if (class_exists(IniHelper::class)) {
                    $created = IniHelper::writeFile($themesIniFile, $defaultThemesConfig, true);
                } else {
                    $iniContent = self::generateIniContent($defaultThemesConfig);
                    $created = @file_put_contents($themesIniFile, $iniContent) !== false;
                }

                if ($created && file_exists($themesIniFile)) {
                    @chmod($themesIniFile, 0644);
                } else {
                    error_log("ConfigurationInitializer: Failed to create themes.ini file: {$themesIniFile}");
                }
            } catch (\Throwable $e) {
                error_log("ConfigurationInitializer: Error creating themes.ini: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
            }
        }
    }

    /**
     * Создание всех необходимых storage директорий с .htaccess файлами
     *
     * @return void
     */
    private static function ensureStorageDirectories(): void
    {
        if (!class_exists(PathResolver::class)) {
            return;
        }

        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        $storageBase = PathResolver::storage();

        // Список директорий, которые нужно создать
        $directories = [
            'cache',
            'logs',
            'sessions',
            'temp',
            'config',
        ];

        // Директории, для которых нужно создать .htaccess (как в storage2)
        $directoriesWithHtaccess = ['cache', 'sessions', 'temp'];

        foreach ($directories as $dir) {
            $dirPath = $storageBase . $ds . $dir;

            // Создаем директорию, если её нет
            if (!is_dir($dirPath)) {
                if (!@mkdir($dirPath, 0755, true) && !is_dir($dirPath)) {
                    error_log("ConfigurationInitializer: Failed to create storage directory: {$dirPath}");
                    continue;
                }
            }

            // Создаем .htaccess файл только для определенных директорий
            if (in_array($dir, $directoriesWithHtaccess, true)) {
                self::ensureHtaccessFile($dirPath);
            }
        }
    }

    /**
     * Создание .htaccess файла для защиты директории от прямого доступа
     *
     * @param string $dirPath Путь к директории
     * @return void
     */
    private static function ensureHtaccessFile(string $dirPath): void
    {
        $htaccessPath = $dirPath . DS . '.htaccess';

        // Если .htaccess уже существует, не перезаписываем
        if (file_exists($htaccessPath)) {
            return;
        }

        // Содержимое .htaccess для запрета прямого доступа
        $htaccessContent = "Deny from all\n";

        try {
            $created = @file_put_contents($htaccessPath, $htaccessContent) !== false;

            if ($created && file_exists($htaccessPath)) {
                @chmod($htaccessPath, 0644);
            } else {
                error_log("ConfigurationInitializer: Failed to create .htaccess file: {$htaccessPath}");
            }
        } catch (\Throwable $e) {
            error_log("ConfigurationInitializer: Error creating .htaccess: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
        }
    }

    /**
     * Создание корневого .htaccess файла для роутинга
     *
     * @return void
     */
    private static function ensureRootHtaccess(): void
    {
        if (!class_exists(PathResolver::class)) {
            return;
        }

        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        $rootDir = PathResolver::root();
        $htaccessPath = $rootDir . $ds . '.htaccess';

        // Если .htaccess уже существует, не перезаписываем
        if (file_exists($htaccessPath)) {
            return;
        }

        // Содержимое корневого .htaccess для роутинга
        $htaccessContent = "# Flowaxy CMS - Apache Rewrite Rules\n";
        $htaccessContent .= "# Правила перезапису URL для роутингу через PHP\n\n";
        $htaccessContent .= "<IfModule mod_rewrite.c>\n";
        $htaccessContent .= "    # Увімкнення механізму перезапису URL\n";
        $htaccessContent .= "    RewriteEngine On\n\n";
        $htaccessContent .= "    # Виключаємо існуючі файли та директорії з роутером\n";
        $htaccessContent .= "    RewriteCond %{REQUEST_FILENAME} -f [OR]\n";
        $htaccessContent .= "    RewriteCond %{REQUEST_FILENAME} -d\n";
        $htaccessContent .= "    RewriteRule ^ - [L]\n\n";
        $htaccessContent .= "    # Всі інші запити відправляємо в index.php для обробки роутером\n";
        $htaccessContent .= "    RewriteRule ^ index.php [L]\n";
        $htaccessContent .= "</IfModule>\n\n";
        $htaccessContent .= "# Вимкнення автоматичної індексації директорій (безпека)\n";
        $htaccessContent .= "<IfModule mod_autoindex.c>\n";
        $htaccessContent .= "    Options -Indexes\n";
        $htaccessContent .= "</IfModule>\n";

        try {
            $created = @file_put_contents($htaccessPath, $htaccessContent) !== false;

            if ($created && file_exists($htaccessPath)) {
                @chmod($htaccessPath, 0644);
            } else {
                error_log("ConfigurationInitializer: Failed to create root .htaccess file: {$htaccessPath}");
            }
        } catch (\Throwable $e) {
            error_log("ConfigurationInitializer: Error creating root .htaccess: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
        }
    }

    /**
     * Создание папки uploads с .htaccess файлом для защиты от выполнения PHP
     *
     * @return void
     */
    private static function ensureUploadsDirectory(): void
    {
        if (!class_exists(PathResolver::class)) {
            return;
        }

        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        $uploadsDir = PathResolver::uploads();

        try {
            // Создаем директорию uploads, если её нет
            if (!is_dir($uploadsDir)) {
                if (!@mkdir($uploadsDir, 0755, true) && !is_dir($uploadsDir)) {
                    error_log("ConfigurationInitializer: Failed to create uploads directory: {$uploadsDir}");
                    return;
                }
            }

            // Создаем .htaccess файл для защиты от выполнения PHP
            $htaccessPath = $uploadsDir . $ds . '.htaccess';

            // Если .htaccess уже существует, не перезаписываем
            if (file_exists($htaccessPath)) {
                return;
            }

            // Содержимое .htaccess для защиты uploads директории
            $htaccessContent = "# Защита директории uploads\n";
            $htaccessContent .= "# Запрет выполнения PHP файлов (безопасность)\n";
            $htaccessContent .= "<FilesMatch \"\\.(php|php3|php4|php5|phtml|pl|py|jsp|asp|sh|cgi)$\">\n";
            $htaccessContent .= "    <IfModule mod_authz_core.c>\n";
            $htaccessContent .= "        Require all denied\n";
            $htaccessContent .= "    </IfModule>\n";
            $htaccessContent .= "    <IfModule !mod_authz_core.c>\n";
            $htaccessContent .= "        Order allow,deny\n";
            $htaccessContent .= "        Deny from all\n";
            $htaccessContent .= "    </IfModule>\n";
            $htaccessContent .= "</FilesMatch>\n\n";
            $htaccessContent .= "# Включение индексации файлов (для просмотра загруженных файлов)\n";
            $htaccessContent .= "<IfModule mod_autoindex.c>\n";
            $htaccessContent .= "    Options +Indexes\n";
            $htaccessContent .= "</IfModule>\n";

            $created = @file_put_contents($htaccessPath, $htaccessContent) !== false;

            if ($created && file_exists($htaccessPath)) {
                @chmod($htaccessPath, 0644);
            } else {
                error_log("ConfigurationInitializer: Failed to create uploads .htaccess file: {$htaccessPath}");
            }
        } catch (\Throwable $e) {
            error_log("ConfigurationInitializer: Error creating uploads directory: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine());
        }
    }
}
