<?php

declare(strict_types=1);

namespace Flowaxy\Support\Managers;

use Exception;
use Flowaxy\Bootstrap\ProtocolDetector;
use Flowaxy\Core\System\Base\BaseModule;
use Flowaxy\Core\System\PathResolver;
use Flowaxy\Domain\Theme\Services\ActivateThemeService;
use Flowaxy\Domain\Theme\Services\ThemeSettingsRepositoryInterface;
use Flowaxy\Domain\Theme\Services\UpdateThemeSettingsService;
use Flowaxy\Infrastructure\Persistence\Database\Database;
use Flowaxy\Infrastructure\Persistence\Repositories\ThemeRepository;
use Flowaxy\Infrastructure\Persistence\Repositories\ThemeSettingsRepository;
use Flowaxy\Support\Facades\Log;
use Flowaxy\Support\Helpers\CacheHelper;
use Flowaxy\Support\Helpers\ClassLoaderHelper;
use Flowaxy\Support\Helpers\DatabaseHelper;
use Flowaxy\Support\Helpers\FileHelper;
use Flowaxy\Support\Helpers\JsonHelper;
use Flowaxy\Support\Helpers\UrlHelper;
use Flowaxy\Support\Validation\Validator;
use Flowaxy\Support\Managers\ThemeLoader;
use Error;
use PDO;
use PDOException;
use Throwable;

use const DS;

// Модуль управління темами
// Управління темами та їх налаштуваннями
final class ThemeManager extends BaseModule
{
    private ?array $activeTheme = null;
    private array $themeSettings = [];
    private ?string $lastActivationError = null;

    // Ініціалізація модуля
    protected function init(): void
    {
        $this->loadActiveTheme();
        $this->initializeThemes();
    }

    /**
     * Ініціалізація тем (завантаження через ThemeLoader)
     *
     * @return void
     */
    private function initializeThemes(): void
    {
        if (class_exists(ThemeLoader::class)) {
            try {
                $themesDir = $this->getThemesBaseDir();
                ThemeLoader::initialize($themesDir);

                // Завантажуємо всі теми
                $allThemes = $this->getAllThemes();
                foreach ($allThemes as $theme) {
                    if (isset($theme['slug'])) {
                        try {
                            ThemeLoader::load($theme['slug'], $theme);
                        } catch (Throwable $e) {
                            try {
                                Log::Error("Помилка ініціалізації теми", ['exception' => $e, 'slug' => $theme['slug']]);
                            } catch (Throwable $logError) {
                                // Ignore logging errors
                            }
                        }
                    }
                }

                // Ініціалізуємо активну тему
                $activeTheme = $this->getActiveTheme();
                if ($activeTheme !== null && isset($activeTheme['slug'])) {
                    $themeInstance = ThemeLoader::get($activeTheme['slug']);
                    if ($themeInstance !== null && method_exists($themeInstance, 'init')) {
                        $themeInstance->init();
                    }
                }
            } catch (Throwable $e) {
                try {
                    Log::Error("Помилка ініціалізації тем", ['exception' => $e]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
            }
        }
    }

    /**
     * Реєстрація хуків модуля
     */
    public function registerHooks(): void
    {
        // Модуль ThemeManager не реєструє хуки
    }

    /**
     * Отримання інформації про модуль
     *
     * @return array<string, string>
     */
    public function getInfo(): array
    {
        return [
            'name' => 'ThemeManager',
            'title' => 'Менеджер тем',
            'description' => 'Управління темами та їх налаштуваннями',
            'version' => '1.0.0 Alpha prerelease',
            'author' => 'Flowaxy CMS',
        ];
    }

    /**
     * Отримання API методів модуля
     *
     * @return array<string, string>
     */
    public function getApiMethods(): array
    {
        return [
            'getActiveTheme' => 'Отримання активної теми',
            'getAllThemes' => 'Отримання всіх тем',
            'getTheme' => 'Отримання теми за slug',
            'activateTheme' => 'Активація теми',
            'getSetting' => 'Отримання налаштування теми',
            'setSetting' => 'Збереження налаштування теми',
            'supportsCustomization' => 'Перевірка підтримки кастомізації',
            'hasScssSupport' => 'Перевірка підтримки SCSS',
            'compileScss' => 'Компіляція SCSS',
        ];
    }

    /**
     * Завантаження активної теми з кешуванням
     * Отримує активну тему з site_settings, потім завантажує дані з файлової системи
     *
     * @return void
     */
    private function loadActiveTheme(): void
    {
        // Використовуємо кешування для активної теми (БД не требуется)
        $cacheKey = 'active_theme_slug';
        $activeSlug = CacheHelper::remember($cacheKey, function () {
            try {
                // Читаем активную тему из storage/config/system/themes.ini (статус activated)
                if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                    $slug = \Flowaxy\Infrastructure\Config\ThemeConfigManager::getActive();

                    // Валідація slug
                    if ($slug && ! Validator::validateSlug($slug)) {
                        try {
                            Log::Warning("Невірний slug активної теми з конфігурації", ['slug' => $slug]);
                        } catch (Throwable $e) {
                            // Ignore logging errors
                        }
                        return null;
                    }

                    return $slug;
                }
            } catch (Throwable $e) {
                try {
                    Log::Error('Помилка завантаження активної теми', ['exception' => $e]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
            }
            return null;
        }, 60); // Кешуємо на 1 хвилину (менше час для швидкого оновлення)

        if ($activeSlug) {
            // Завантажуємо тему з файлової системи
            $theme = $this->getTheme($activeSlug);
            if ($theme !== null && is_array($theme)) {
                $this->activeTheme = $theme;
                $this->loadThemeSettings($theme['slug']);
            }
        }
    }

    /**
     * Завантаження налаштувань теми з кешуванням
     *
     * @param string $themeSlug Slug теми
     * @return void
     */
    private function loadThemeSettings(string $themeSlug): void
    {
        if (! Validator::validateSlug($themeSlug)) {
            Log::warning("ThemeManager: Invalid theme slug", ['theme_slug' => $themeSlug]);
            return;
        }

        // Отримуємо збережені налаштування з бази даних
        $cacheKey = 'theme_settings_' . $themeSlug;
        $savedSettings = CacheHelper::remember($cacheKey, function () use ($themeSlug) {
            try {
                $repository = $this->getSettingsRepository();
                // Використовуємо getAll() для отримання всіх налаштувань
                if (method_exists($repository, 'getAll')) {
                    return $repository->getAll($themeSlug);
                }
                return [];
            } catch (Throwable $e) {
                try {
                    Log::Error('Помилка завантаження налаштувань теми', ['exception' => $e]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
                return [];
            }
        }, 3600);

        // Отримуємо значення за замовчуванням з конфігурації теми
        $themeConfig = $this->getThemeConfig($themeSlug);
        $defaultSettings = $themeConfig['default_settings'] ?? [];

        // Об'єднуємо: спочатку значення за замовчуванням, потім збережені значення
        $this->themeSettings = array_merge($defaultSettings, $savedSettings);
    }

    /**
     * Отримання активної теми
     *
     * @return array<string, mixed>|null
     */
    public function getActiveTheme(): ?array
    {
        // Якщо активна тема не завантажена, намагаємося завантажити
        if (empty($this->activeTheme)) {
            $this->loadActiveTheme();
        }

        return $this->activeTheme;
    }

    /**
     * Примусова перезавантаження активної теми
     *
     * @return void
     */
    public function reloadActiveTheme(): void
    {
        // Очищаємо кеш
        CacheHelper::forget('active_theme_slug');
        CacheHelper::forget('active_theme');
        // Перезагружаем
        $this->loadActiveTheme();
    }

    /**
     * Отримання всіх тем (з файлової системи)
     * Автоматично виявляє теми за наявністю Theme.php
     *
     * @return array
     */
    public function getAllThemes(): array
    {
        $themesDir = $this->getThemesBaseDir();

        if (! is_dir($themesDir)) {
            try {
                Log::Error("Директорія тем не знайдена", ['themesDir' => $themesDir]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return [];
        }

        /**
         * @return array<int, array<string, mixed>>
         */
        return CacheHelper::remember('all_themes_filesystem', function () use ($themesDir): array {
            $themes = [];
            $directories = glob($themesDir . '*', GLOB_ONLYDIR);

            foreach ($directories as $dir) {
                $themeSlug = basename($dir);

                // Используем ThemeMetadataHelper для чтения метаданных из Theme.php
                if (class_exists(\Flowaxy\Support\Helpers\ThemeMetadataHelper::class)) {
                    $metadata = \Flowaxy\Support\Helpers\ThemeMetadataHelper::readMetadata($themeSlug);

                    if (empty($metadata)) {
                        try {
                            Log::Warning("Неможливо прочитати Theme.php", ['themeSlug' => $themeSlug]);
                        } catch (Throwable $e) {
                            // Ignore logging errors
                        }
                        continue;
                    }

                    if (is_array($metadata) && !empty($metadata['slug'])) {
                        if (empty($metadata['slug'])) {
                            $metadata['slug'] = $themeSlug;
                        }

                        $isActive = $this->isThemeActive($metadata['slug'] ?? $themeSlug);

                        $theme = [
                            'slug' => $metadata['slug'],
                            'name' => $metadata['name'] ?? ucfirst($themeSlug),
                            'description' => $metadata['description'] ?? '',
                            'version' => $metadata['version'] ?? '1.0.0',
                            'author' => $metadata['author'] ?? '',
                            'author_url' => $metadata['author_url'] ?? '',
                            'is_active' => $isActive ? 1 : 0,
                            'screenshot' => $this->getThemeScreenshot($themeSlug),
                            'supports_customization' => $metadata['supports_customization'] ?? false,
                        ];

                        $themes[$themeSlug] = $theme;
                    } else {
                        try {
                            Log::Warning("Невірні метадані в Theme.php", ['themeSlug' => $themeSlug]);
                        } catch (Throwable $e) {
                            // Ignore logging errors
                        }
                    }
                } else {
                    try {
                        Log::Warning("ThemeMetadataHelper не знайдено", ['themeSlug' => $themeSlug]);
                    } catch (Throwable $e) {
                        // Ignore logging errors
                    }
                }
            }

            usort($themes, function ($a, $b) {
                if ($a['is_active'] != $b['is_active']) {
                    return $b['is_active'] - $a['is_active'];
                }

                return strcmp($a['name'], $b['name']);
            });

            return array_values($themes);
        }, 300);
    }

    // Перевірка активності теми з site_settings
    private function isThemeActive(string $themeSlug): bool
    {
        // Проверяем только обязательные параметры (БД не требуется)
        if (empty($themeSlug)) {
            return false;
        }

        try {
            $cacheKey = 'active_theme_check_' . md5($themeSlug);

            return CacheHelper::remember($cacheKey, function () use ($themeSlug): bool {
                try {
                    // Читаем активную тему из storage/config/system/themes.ini (статус activated)
                    if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                        return \Flowaxy\Infrastructure\Config\ThemeConfigManager::isActive($themeSlug);
                    }
                } catch (Throwable $e) {
                    try {
                        Log::Error('Помилка перевірки активності теми', ['exception' => $e]);
                    } catch (Throwable $logError) {
                        // Ignore logging errors
                    }
                    return false;
                }
                return false;
            }, 60);
        } catch (Exception $e) {
            try {
                Log::Error('Помилка перевірки активності теми', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    // Отримання шляху до скріншота теми
    private function getThemeScreenshot(string $themeSlug): ?string
    {
        $themesDir = $this->getThemesBaseDir();
        $screenshotPath = $themesDir . $themeSlug . '/screenshot.png';

        if (FileHelper::exists($screenshotPath)) {
            // Використовуємо UrlHelper для отримання актуального URL з правильним протоколом
            if (class_exists(UrlHelper::class)) {
                return UrlHelper::site('/themes/' . $themeSlug . '/screenshot.png');
            }
            // Fallback на константу, якщо UrlHelper недоступний
            $siteUrl = defined('SITE_URL') ? SITE_URL : '';

            return $siteUrl . '/themes/' . $themeSlug . '/screenshot.png';
        }

        return null;
    }

    // Отримання теми за slug
    public function getTheme(string $slug): ?array
    {
        $allThemes = $this->getAllThemes();
        foreach ($allThemes as $theme) {
            if ($theme['slug'] === $slug) {
                return $theme;
            }
        }

        return null;
    }

    // Активація теми
    public function activateTheme(string $slug): bool
    {
        if (! Validator::validateSlug($slug)) {
            try {
                Log::Error("Невірний slug теми для активації", ['slug' => $slug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        // Перевіряємо залежності теми (required plugins)
        $requiredPlugins = $this->getThemeRequiredPlugins($slug);
        if (!empty($requiredPlugins)) {
            $missingPlugins = [];
            foreach ($requiredPlugins as $pluginSlug => $pluginName) {
                if (!class_exists(\Flowaxy\Infrastructure\Config\PluginConfigManager::class, false)) {
                    \Flowaxy\Support\Helpers\ClassLoaderHelper::ensureLoaded(\Flowaxy\Infrastructure\Config\PluginConfigManager::class);
                }
                $pluginStatus = \Flowaxy\Infrastructure\Config\PluginConfigManager::getStatus($pluginSlug);
                if ($pluginStatus !== 'active') {
                    $missingPlugins[] = $pluginName;
                }
            }

            if (!empty($missingPlugins)) {
                try {
                    $missingList = implode(', ', $missingPlugins);
                    Log::Warning("Тема {$slug} потребує активних плагінів: {$missingList}", [
                        'theme' => $slug,
                        'missing_plugins' => $missingPlugins,
                    ]);
                } catch (Throwable $e) {
                    // Ignore logging errors
                }
                // Сохраняем информацию о недостающих плагинах для отображения пользователю
                $this->lastActivationError = 'Тема потребує активних плагінів: ' . implode(', ', $missingPlugins);
                return false;
            }
        }

        try {
            // Создаем сервис напрямую, так как DI контейнер может возвращать lazy proxy без метода execute
            $themeRepository = new ThemeRepository();
            $service = new ActivateThemeService($themeRepository);
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка створення сервісу активації теми', [
                    'exception' => $e,
                    'message' => $e->getMessage(),
                    'trace' => $e->getTraceAsString()
                ]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }

        // Перевіряємо, що service є об'єктом з методом execute перед викликом
        if (!is_object($service) || !method_exists($service, 'execute')) {
            try {
                Log::Error('Сервіс не валідний', [
                    'service_type' => gettype($service),
                    'is_object' => is_object($service),
                    'has_execute' => is_object($service) ? method_exists($service, 'execute') : false,
                    'service_class' => is_object($service) ? get_class($service) : 'N/A',
                ]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        $result = $service->execute($slug);

        if ($result) {
            // Активная тема теперь хранится в themes.ini (статус activated)
            // Не обновляем site.php - active_theme больше не используется
            $this->clearThemeCache($slug);
            CacheHelper::forget('active_theme_slug');
            CacheHelper::forget('active_theme');
            $this->activeTheme = null;
            $this->loadActiveTheme();
            $this->lastActivationError = null; // Очищаем ошибку при успешной активации
        }

        return $result;
    }

    /**
     * Отримати список необхідних плагінів для теми
     *
     * @param string $slug
     * @return array<string, string> Масив [plugin_slug => plugin_name]
     */
    private function getThemeRequiredPlugins(string $slug): array
    {
        // Спочатку пробуємо отримати з метаданих теми
        if (class_exists(\Flowaxy\Support\Helpers\ThemeMetadataHelper::class)) {
            $metadata = \Flowaxy\Support\Helpers\ThemeMetadataHelper::readMetadata($slug);
            if (isset($metadata['requires_plugins']) && is_array($metadata['requires_plugins'])) {
                return $metadata['requires_plugins'];
            }
        }

        // Якщо в метаданих немає, пробуємо отримати через екземпляр теми
        try {
            $theme = $this->getTheme($slug);
            if ($theme && is_array($theme)) {
                // Завантажуємо екземпляр теми через ThemeLoader
                if (class_exists(\Flowaxy\Support\Managers\ThemeLoader::class)) {
                    $themeInstance = \Flowaxy\Support\Managers\ThemeLoader::get($slug);
                    if ($themeInstance && method_exists($themeInstance, 'getRequiredPlugins')) {
                        $requiredPlugins = $themeInstance->getRequiredPlugins();
                        if (!empty($requiredPlugins)) {
                            return $requiredPlugins;
                        }
                    }
                }
            }
        } catch (Throwable $e) {
            // Ігноруємо помилки при отриманні екземпляра теми
        }

        return [];
    }

    /**
     * Отримати останню помилку активації теми
     *
     * @return string|null
     */
    public function getLastActivationError(): ?string
    {
        return $this->lastActivationError;
    }

    // Деактивація теми
    public function deactivateTheme(string $slug): bool
    {
        // Проверяем только обязательные параметры (БД не требуется для деактивации тем)
        if (empty($slug)) {
            return false;
        }

        if (! Validator::validateSlug($slug)) {
            try {
                Log::Error("Невірний slug теми для деактивації", ['slug' => $slug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        try {
            // Обновляем статус темы в themes.ini (deactivated)
            if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                \Flowaxy\Infrastructure\Config\ThemeConfigManager::setStatus($slug, 'deactivated');
            }

            // Очищаємо кеш
            $this->clearThemeCache($slug);
            CacheHelper::forget('active_theme_slug');
            CacheHelper::forget('active_theme');

            // Очищаємо активну тему з пам'яті
            $this->activeTheme = null;

            return true;
        } catch (Exception $e) {
            try {
                Log::Error('Помилка деактивації теми', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    // Ініціалізація налаштувань за замовчуванням для теми
    private function initializeDefaultSettings(string $themeSlug): bool
    {
        $db = $this->getDB();
        if ($db === null || empty($themeSlug)) {
            return false;
        }

        if (! Validator::validateSlug($themeSlug)) {
            try {
                Log::Error("Невірний slug теми для налаштувань за замовчуванням", ['themeSlug' => $themeSlug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        try {
            $themeConfig = $this->getThemeConfig($themeSlug);
            $defaultSettings = $themeConfig['default_settings'] ?? [];

            if (empty($defaultSettings) || ! is_array($defaultSettings)) {
                return true;
            }

            $stmt = $db->prepare('SELECT COUNT(*) as count FROM theme_settings WHERE theme_slug = ?');
            $stmt->execute([$themeSlug]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);

            if (isset($result['count']) && (int)$result['count'] === 0) {
                Database::getInstance()->transaction(function (PDO $db) use ($themeSlug, $defaultSettings): void {
                    foreach ($defaultSettings as $key => $value) {
                        if (empty($key) || ! Validator::validateString($key, 1, 255)) {
                            try {
                                Log::Warning("Невірний ключ налаштування за замовчуванням", ['key' => $key]);
                            } catch (Throwable $e) {
                                // Ignore logging errors
                            }
                            continue;
                        }

                        $valueStr = is_scalar($value) ? (string)$value : json_encode($value, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);

                        $stmt = $db->prepare('
                            INSERT INTO theme_settings (theme_slug, setting_key, setting_value)
                            VALUES (?, ?, ?)
                        ');
                        $stmt->execute([$themeSlug, $key, $valueStr]);
                    }
                });

                $this->loadThemeSettings($themeSlug);
                CacheHelper::forget('theme_settings_' . $themeSlug);
            }

            return true;
        } catch (Exception $e) {
            try {
                Log::Error('Помилка ініціалізації налаштувань за замовчуванням', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    /**
     * Отримання налаштування теми
     */
    public function getSetting(string $key, $default = null)
    {
        if (empty($key)) {
            return $default;
        }

        return $this->themeSettings[$key] ?? $default;
    }

    /**
     * Отримання всіх налаштувань теми
     */
    public function getSettings(): array
    {
        return $this->themeSettings;
    }

    /**
     * Отримання налаштувань теми за slug
     *
     * @param string $themeSlug Slug теми
     * @return array Масив налаштувань теми
     */
    /**
     * @param string $themeSlug
     * @return array<string, mixed>
     */
    public function getThemeSettings(string $themeSlug): array
    {
        if (! Validator::validateSlug($themeSlug)) {
            try {
                Log::Error("Невірний slug теми", ['themeSlug' => $themeSlug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return [];
        }

        // Отримуємо налаштування з бази даних
        $cacheKey = 'theme_settings_' . $themeSlug;
        $savedSettings = CacheHelper::remember($cacheKey, function () use ($themeSlug) {
            try {
                $repository = $this->getSettingsRepository();
                // Використовуємо getAll() для отримання всіх налаштувань
                if (method_exists($repository, 'getAll')) {
                    return $repository->getAll($themeSlug);
                }
                return [];
            } catch (Throwable $e) {
                try {
                    Log::Error('Помилка отримання налаштувань теми', ['exception' => $e]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
                return [];
            }
        }, 3600);

        // Отримуємо значення за замовчуванням з конфігурації теми
        $themeConfig = $this->getThemeConfig($themeSlug);
        $defaultSettings = $themeConfig['default_settings'] ?? [];

        // Об'єднуємо: спочатку значення за замовчуванням, потім збережені значення
        return array_merge($defaultSettings, $savedSettings);
    }

    /**
     * Збереження налаштування теми
     */
    public function setSetting(string $key, $value): bool
    {
        if ($this->activeTheme === null || empty($key)) {
            return false;
        }

        if (! Validator::validateString($key, 1, 255)) {
            try {
                Log::Error("Невірний ключ налаштування", ['key' => $key]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        $themeSlug = $this->activeTheme['slug'];

        try {
            $service = $this->getUpdateSettingsService();
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка сервісу збереження налаштування теми', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            $service = new UpdateThemeSettingsService(
                new ThemeSettingsRepository(),
                new ThemeRepository()
            );
        }

        $result = $service->execute($themeSlug, [$key => $value]);

        if ($result) {
            $this->themeSettings[$key] = $value;
        }

        return $result;
    }

    /**
     * Збереження кількох налаштувань теми
     */
    public function setSettings(array $settings): bool
    {
        if ($this->activeTheme === null) {
            return false;
        }

        if (empty($settings)) {
            return false;
        }

        $themeSlug = $this->activeTheme['slug'];
        $filtered = [];
        foreach ($settings as $key => $value) {
            if (is_string($key) && Validator::validateString($key, 1, 255)) {
                $filtered[$key] = $value;
            }
        }

        if (empty($filtered)) {
            return false;
        }

        try {
            $service = $this->getUpdateSettingsService();
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка сервісу збереження налаштувань теми', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            $service = new UpdateThemeSettingsService(
                new ThemeSettingsRepository(),
                new ThemeRepository()
            );
        }

        $result = $service->execute($themeSlug, $filtered);
        if ($result) {
            $repository = $this->getSettingsRepository();
            // Використовуємо getAll() якщо доступний, інакше get() з репозиторію
            if (method_exists($repository, 'getAll')) {
                $this->themeSettings = $repository->getAll($themeSlug);
            } elseif ($repository instanceof ThemeSettingsRepository) {
                $this->themeSettings = $repository->get($themeSlug);
            } else {
                $this->themeSettings = [];
            }
        }

        return $result;
    }

    /**
     * Отримання шляху до теми
     */
    public function getThemePath(?string $themeSlug = null): string
    {
        $theme = $themeSlug ? $this->getTheme($themeSlug) : $this->activeTheme;

        $themesBaseDir = $this->getThemesBaseDir();

        if ($theme === null || ! isset($theme['slug'])) {
            return $themesBaseDir . 'default/';
        }

        $slug = $theme['slug'];
        if (! Validator::validateSlug($slug)) {
            try {
                Log::Error("Невірний slug теми для шляху", ['slug' => $slug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return $themesBaseDir . 'default/';
        }

        $path = $themesBaseDir . $slug . '/';

        return FileHelper::exists($path) ? $path : $themesBaseDir . 'default/';
    }

    /**
     * Отримання URL теми
     */
    public function getThemeUrl(?string $themeSlug = null): string
    {
        $theme = $themeSlug ? $this->getTheme($themeSlug) : $this->activeTheme;

        // Використовуємо UrlHelper для отримання актуального протоколу з налаштувань
        if (class_exists(UrlHelper::class)) {
            $protocol = UrlHelper::getProtocol();
            $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
            $baseUrl = $protocol . $host;
        } elseif (class_exists(ProtocolDetector::class)) {
            $protocol = ProtocolDetector::detect();
            $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
            $baseUrl = $protocol . $host;
        } else {
            // Fallback на автоматическое определение
            $protocol = 'http://';
            if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ||
                (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') ||
                (isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443)) {
                $protocol = 'https://';
            }
            $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
            $baseUrl = $protocol . $host;
        }

        if ($theme === null || ! isset($theme['slug'])) {
            return $baseUrl . '/themes/default/';
        }

        $slug = $theme['slug'];
        if (! Validator::validateSlug($slug)) {
            try {
                Log::Error("Невірний slug теми для URL", ['slug' => $slug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }

            return $baseUrl . '/themes/default/';
        }

        return $baseUrl . '/themes/' . $slug . '/';
    }

    /**
     * Перевірка існування теми
     */
    public function themeExists(string $slug): bool
    {
        if (empty($slug)) {
            return false;
        }
        $theme = $this->getTheme($slug);

        return $theme !== null;
    }

    /**
     * Валидация структуры темы
     */
    public function validateThemeStructure(string $slug): array
    {
        $errors = [];

        if (! Validator::validateSlug($slug)) {
            $errors[] = "Невірний slug теми: {$slug}";
            return ['valid' => false, 'errors' => $errors, 'warnings' => []];
        }

        $themesBaseDir = $this->getThemesBaseDir();
        $themePath = $themesBaseDir . $slug . DS;

        if (! is_dir($themePath)) {
            $errors[] = "Директорія теми не знайдена: {$themePath}";
            return ['valid' => false, 'errors' => $errors, 'warnings' => []];
        }

        // Проверяем только наличие файла Theme.php
        $themeFile = $themePath . 'Theme.php';
        if (! FileHelper::exists($themeFile)) {
            $errors[] = "Відсутній обов'язковий файл: Theme.php";
            return ['valid' => false, 'errors' => $errors, 'warnings' => []];
        }

        // Проверяем, что Theme.php можно прочитать
        try {
            if (class_exists(\Flowaxy\Support\Helpers\ThemeMetadataHelper::class)) {
                $config = \Flowaxy\Support\Helpers\ThemeMetadataHelper::readMetadata($slug);
                if (empty($config)) {
                    $errors[] = 'Неможливо прочитати Theme.php';
                } else {
                    // Проверяем только обязательные поля
                    $requiredConfigKeys = ['name', 'version', 'slug'];
                    foreach ($requiredConfigKeys as $key) {
                        if (! isset($config[$key]) || empty($config[$key])) {
                            $errors[] = "Відсутнє обов'язкове поле в Theme.php: {$key}";
                        }
                    }
                }
            } else {
                $errors[] = 'ThemeMetadataHelper не знайдено';
            }
        } catch (Exception $e) {
            $errors[] = 'Помилка завантаження Theme.php: ' . $e->getMessage();
        }

        return [
            'valid' => empty($errors),
            'errors' => $errors,
            'warnings' => [],
        ];
    }

    /**
     * Встановлення теми
     */
    public function installTheme(string $slug, string $name, string $description = '', string $version = '1.0.0', string $author = ''): bool
    {
        // Проверяем только обязательные параметры (БД не требуется для установки тем)
        if (empty($slug) || empty($name)) {
            return false;
        }

        if (! Validator::validateSlug($slug)) {
            try {
                Log::Error("Невірний slug теми для встановлення", ['slug' => $slug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        if (! Validator::validateString($name, 1, 255)) {
            try {
                Log::Error("Невірна назва теми", ['name' => $name]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        // Проверяем только наличие Theme.php
        $themesBaseDir = $this->getThemesBaseDir();
        $themePath = $themesBaseDir . $slug . DS;
        $themeFile = $themePath . 'Theme.php';

        if (! is_dir($themePath) || ! FileHelper::exists($themeFile)) {
            try {
                Log::Error("Тема не знайдена або відсутній Theme.php", ['slug' => $slug, 'path' => $themePath]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        $themeConfig = $this->getThemeConfig($slug);
        if (! empty($themeConfig)) {
            $name = $themeConfig['name'] ?? $name;
            $description = $themeConfig['description'] ?? $description;
            $version = $themeConfig['version'] ?? $version;
            $author = $themeConfig['author'] ?? $author;
        }

        try {
            // Создаем файл конфигурации темы в storage/config/themes/{slug}.ini
            if (class_exists(\Flowaxy\Infrastructure\Config\ThemeSettingsManager::class)) {
                $themeConfig = $this->getThemeConfig($slug);
                $defaultSettings = $themeConfig['default_settings'] ?? [];
                if (!empty($defaultSettings)) {
                    \Flowaxy\Infrastructure\Config\ThemeSettingsManager::saveSettings($slug, $defaultSettings);
                } else {
                    // Создаем пустой файл конфигурации
                    \Flowaxy\Infrastructure\Config\ThemeSettingsManager::saveSettings($slug, []);
                }
            }

            // Устанавливаем статус темы в themes.ini (без автоматической активации)
            if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                \Flowaxy\Infrastructure\Config\ThemeConfigManager::setStatus($slug, 'installed');
            }

            CacheHelper::forget('all_themes_filesystem');
            CacheHelper::forget('theme_' . $slug);

            return true;
        } catch (Exception $e) {
            try {
                Log::Error('Помилка встановлення теми', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    /**
     * Удаление темы
     * Удаляет файл конфигурации, запись из themes.ini и файлы темы
     *
     * @param string $slug Slug темы
     * @return bool Успех операции
     */
    public function uninstallTheme(string $slug): bool
    {
        if (! Validator::validateSlug($slug)) {
            try {
                Log::Error("Невірний slug теми для видалення", ['slug' => $slug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return false;
        }

        try {
            // Проверяем, что тема не активна
            if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                $status = \Flowaxy\Infrastructure\Config\ThemeConfigManager::getStatus($slug);
                if ($status === 'activated') {
                    try {
                        Log::Error('Неможливо видалити активну тему', ['slug' => $slug]);
                    } catch (Throwable $e) {
                        // Ignore logging errors
                    }
                    return false;
                }
            }

            // 1. Удаляем файл конфигурации темы из storage/config/themes/{slug}.ini
            $themesConfigDir = PathResolver::storageConfig() . DS . 'themes';
            $themeConfigFile = $themesConfigDir . DS . $slug . '.ini';
            if (FileHelper::exists($themeConfigFile)) {
                @unlink($themeConfigFile);
                try {
                    Log::Info('Файл конфігурації теми видалено', ['file' => $themeConfigFile, 'slug' => $slug]);
                } catch (Throwable $e) {
                    // Ignore logging errors
                }
            }

            // 2. Удаляем запись о теме из storage/config/system/themes.ini
            if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                // Используем ThemeConfigManager для удаления записи
                $themesIniPath = PathResolver::storageConfig() . DS . 'system' . DS . 'themes.ini';
                if (FileHelper::exists($themesIniPath)) {
                    $themesConfig = [];
                    if (class_exists(\Flowaxy\Support\Helpers\IniHelper::class)) {
                        $themesConfig = \Flowaxy\Support\Helpers\IniHelper::readFile($themesIniPath, true) ?: [];
                    } else {
                        $themesConfig = parse_ini_file($themesIniPath, true) ?: [];
                    }

                    if (isset($themesConfig['themes']) && is_array($themesConfig['themes'])) {
                        unset($themesConfig['themes'][$slug]);

                        // Записываем обратно
                        if (class_exists(\Flowaxy\Support\Helpers\IniHelper::class)) {
                            \Flowaxy\Support\Helpers\IniHelper::writeFile($themesIniPath, $themesConfig);
                        } else {
                            // Fallback: записываем напрямую
                            $content = "[themes]\n";
                            foreach ($themesConfig['themes'] ?? [] as $themeSlug => $themeStatus) {
                                $content .= "{$themeSlug} = {$themeStatus}\n";
                            }
                            @file_put_contents($themesIniPath, $content);
                        }
                    }
                }
            }

            // 3. Удаляем файлы темы (директорию темы)
            $themePath = PathResolver::themes() . DS . $slug;
            if (FileHelper::isDirectory($themePath)) {
                if (class_exists(\Flowaxy\Support\Helpers\ResourceCleanupHelper::class)) {
                    \Flowaxy\Support\Helpers\ResourceCleanupHelper::deleteDirectory($themePath);
                } else {
                    // Fallback: удаляем через рекурсивное удаление
                    $this->deleteDirectoryRecursive($themePath);
                }
                try {
                    Log::Info('Директорію теми видалено', ['path' => $themePath, 'slug' => $slug]);
                } catch (Throwable $e) {
                    // Ignore logging errors
                }
            }

            // Очищаем кеш
            $this->clearThemeCache($slug);
            CacheHelper::forget('all_themes_filesystem');
            CacheHelper::forget('theme_' . $slug);

            try {
                Log::Info('Тему успішно видалено', ['slug' => $slug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }

            return true;
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка видалення теми', [
                    'exception' => $e,
                    'slug' => $slug,
                    'message' => $e->getMessage(),
                ]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    /**
     * Рекурсивное удаление директории (fallback)
     *
     * @param string $dir Путь к директории
     * @return bool
     */
    private function deleteDirectoryRecursive(string $dir): bool
    {
        if (!is_dir($dir)) {
            return false;
        }

        $files = array_diff(scandir($dir), ['.', '..']);
        foreach ($files as $file) {
            $path = $dir . DS . $file;
            if (is_dir($path)) {
                $this->deleteDirectoryRecursive($path);
            } else {
                @unlink($path);
            }
        }

        return @rmdir($dir);
    }

    /**
     * Завантаження конфігурації теми з Theme.php
     */
    public function getThemeConfig(?string $themeSlug = null): array
    {
        $theme = $themeSlug ? $this->getTheme($themeSlug) : $this->activeTheme;

        if ($theme === null) {
            return [
                'name' => 'Default',
                'version' => '1.0.0',
                'description' => '',
                'default_settings' => [],
                'available_settings' => [],
            ];
        }

        $slug = $theme['slug'] ?? 'default';

        if (! Validator::validateSlug($slug)) {
            try {
                Log::Error("Невірний slug теми для конфігурації", ['slug' => $slug]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return [
                'name' => $theme['name'] ?? 'Default',
                'version' => $theme['version'] ?? '1.0.0',
                'description' => $theme['description'] ?? '',
                'default_settings' => [],
                'available_settings' => [],
            ];
        }

        $cacheKey = 'theme_config_' . $slug;

        return CacheHelper::remember($cacheKey, function () use ($slug, $theme) {
            // Используем ThemeMetadataHelper для чтения метаданных из Theme.php
            if (class_exists(\Flowaxy\Support\Helpers\ThemeMetadataHelper::class)) {
                try {
                    $config = \Flowaxy\Support\Helpers\ThemeMetadataHelper::readMetadata($slug);
                    if (is_array($config) && !empty($config)) {
                        // Добавляем default_settings и available_settings если они есть
                        $config['default_settings'] = $config['default_settings'] ?? [];
                        $config['available_settings'] = $config['available_settings'] ?? [];
                        return $config;
                    }
                } catch (Exception $e) {
                    try {
                        Log::Error("Помилка завантаження Theme.php", ['exception' => $e, 'slug' => $slug]);
                    } catch (Throwable $logError) {
                        // Ignore logging errors
                    }
                }
            }

            return [
                'name' => $theme['name'] ?? 'Default',
                'version' => $theme['version'] ?? '1.0.0',
                'description' => $theme['description'] ?? '',
                'default_settings' => [],
                'available_settings' => [],
            ];
        }, 3600);
    }

    /**
     * Перевірка підтримки кастомізації темою
     */
    public function supportsCustomization(?string $themeSlug = null): bool
    {
        $theme = $themeSlug ? $this->getTheme($themeSlug) : $this->activeTheme;
        if (! $theme) {
            return false;
        }

        $themeConfig = $this->getThemeConfig($theme['slug']);
        if (isset($themeConfig['supports_customization'])) {
            return (bool)$themeConfig['supports_customization'];
        }

        $themePath = $this->getThemePath($theme['slug']);

        return FileHelper::exists($themePath . 'customizer.php');
    }

    /**
     * Перевірка підтримки навігації темою
     */
    public function supportsNavigation(?string $themeSlug = null): bool
    {
        $theme = $themeSlug ? $this->getTheme($themeSlug) : $this->activeTheme;
        if (! $theme) {
            return false;
        }

        $themeConfig = $this->getThemeConfig($theme['slug']);

        return (bool)($themeConfig['supports_navigation'] ?? false);
    }

    /**
     * Перевірка підтримки SCSS темою
     */
    public function hasScssSupport(?string $themeSlug = null): bool
    {
        $theme = $themeSlug ? $this->getTheme($themeSlug) : $this->activeTheme;
        if (! $theme) {
            return false;
        }

        $themePath = $this->getThemePath($theme['slug']);
        $scssFile = $themePath . 'assets/scss/main.scss';

        return FileHelper::exists($scssFile) && FileHelper::isReadable($scssFile);
    }

    /**
     * Компиляция SCSS в CSS для темы
     */
    public function compileScss(?string $themeSlug = null, bool $force = false): bool
    {
        $theme = $themeSlug ? $this->getTheme($themeSlug) : $this->activeTheme;
        if (! $theme) {
            return false;
        }

        $themePath = $this->getThemePath($theme['slug']);

                // Используем мигрированный ScssCompiler
                if (!class_exists('Flowaxy\Infrastructure\Compilers\ScssCompiler')) {
                    // Fallback: загружаем через autoloader
                }
                $compiler = new \Flowaxy\Infrastructure\Compilers\ScssCompiler($themePath, 'assets/scss/main.scss', 'assets/css/style.css');

        if (! $compiler->hasScssFiles()) {
            return false;
        }

        $mainFile = $themePath . 'assets/scss/main.scss';
        $outputFile = $themePath . 'assets/css/style.css';

        if ($force || !FileHelper::exists($outputFile)) {
            return $compiler->compile($mainFile, $outputFile);
        }

        return true;
    }

    /**
     * Отримання URL файлу стилів теми
     */
    public function getStylesheetUrl(?string $themeSlug = null, string $cssFile = 'style.css'): string
    {
        $theme = $themeSlug ? $this->getTheme($themeSlug) : $this->activeTheme;
        if (! $theme) {
            return $this->getThemeUrl() . $cssFile;
        }

        $themePath = $this->getThemePath($theme['slug']);

        // SCSS компіляція НЕ виконується під час HTTP-запитів.
        // Якщо тема використовує SCSS — CSS має бути згенерований через CLI-команду.
        if ($this->hasScssSupport($theme['slug'])) {
            $compiledCssFile = $themePath . 'assets/css/style.css';
            if (FileHelper::exists($compiledCssFile) && FileHelper::isReadable($compiledCssFile)) {
                return $this->getThemeUrl($theme['slug']) . 'assets/css/style.css';
            }
            // Лише лог — без UI/response
            error_log("ThemeManager: SCSS підтримується темою '{$theme['slug']}', але CSS не згенерований. Запусти CLI-команду компіляції SCSS.");
        }

        $regularCssFile = $themePath . $cssFile;

        if (FileHelper::exists($regularCssFile) && FileHelper::isReadable($regularCssFile)) {
            return $this->getThemeUrl($theme['slug']) . $cssFile;
        }

        return $this->getThemeUrl($theme['slug']) . $cssFile;
    }

    /**
     * Очищення кешу теми
     */
    public function clearThemeCache(?string $themeSlug = null): void
    {
        // Очищаємо кеш активной теми через CacheHelper
        $keysToForget = ['active_theme', 'active_theme_slug', 'all_themes_filesystem'];

        if ($themeSlug) {
            $keysToForget[] = 'theme_settings_' . $themeSlug;
            $keysToForget[] = 'theme_config_' . $themeSlug;
            $keysToForget[] = 'theme_' . $themeSlug;
            $keysToForget[] = 'active_theme_check_' . md5($themeSlug);
        } else {
            // Очищаємо кеш для всіх тем
            $themesDir = $this->getThemesBaseDir();
            if (is_dir($themesDir)) {
                $directories = glob($themesDir . '*', GLOB_ONLYDIR);
                if ($directories !== false) {
                    foreach ($directories as $dir) {
                        $slug = basename($dir);
                        $keysToForget[] = 'active_theme_check_' . md5($slug);
                        $keysToForget[] = 'theme_config_' . $slug;
                        $keysToForget[] = 'theme_settings_' . $slug;
                    }
                }
            }
        }

        CacheHelper::forgetMultiple($keysToForget);
    }

    private function getSettingsRepository(): ThemeSettingsRepositoryInterface
    {
        if (class_exists(\Flowaxy\Support\Facades\App::class)) {
            $repository = \Flowaxy\Support\Facades\App::make(ThemeSettingsRepositoryInterface::class);
            // Якщо повернуто Closure, викликаємо його
            if ($repository instanceof \Closure) {
                $repository = $repository();
            }
            // Перевіряємо, чи це ThemeSettingsRepositoryInterface
            if ($repository instanceof ThemeSettingsRepositoryInterface) {
                return $repository;
            }
        }

        // Fallback: створюємо напряму
        return new ThemeSettingsRepository();
    }

    private function getEngineDir(): string
    {
        return PathResolver::engine();
    }

    /**
     * Получить timestamp для директории тем (для инвалидации кеша)
     * Использует время модификации всех файлов Theme.php
     *
     * @param string $themesDir
     * @return string
     */
    private function getThemesDirTimestamp(string $themesDir): string
    {
        if (!is_dir($themesDir)) {
            return '0';
        }

        $directories = glob($themesDir . '*', GLOB_ONLYDIR);
        if ($directories === false || empty($directories)) {
            return '0';
        }

        $maxMtime = 0;
        foreach ($directories as $dir) {
            $themeFile = $dir . DS . 'Theme.php';
            if (FileHelper::exists($themeFile)) {
                $mtime = filemtime($themeFile);
                if ($mtime !== false && $mtime > $maxMtime) {
                    $maxMtime = $mtime;
                }
            }
        }

        // Также учитываем время модификации самой директории тем
        $dirMtime = filemtime($themesDir);
        if ($dirMtime !== false && $dirMtime > $maxMtime) {
            $maxMtime = $dirMtime;
        }

        return (string)$maxMtime;
    }

    private function getRootDir(): string
    {
        return PathResolver::root();
    }

    private function getThemesBaseDir(): string
    {
        static $themesDir = null;
        if ($themesDir === null) {
            $dir = PathResolver::themes();
            $real = realpath($dir);
            $themesDir = rtrim($real ?: $dir, DS) . DS;
        }

        return $themesDir;
    }

    private function getUpdateSettingsService(): UpdateThemeSettingsService
    {
        if (class_exists(\Flowaxy\Support\Facades\App::class)) {
            return \Flowaxy\Support\Facades\App::make(UpdateThemeSettingsService::class);
        }

        return new UpdateThemeSettingsService(
            new ThemeSettingsRepository(),
            new ThemeRepository()
        );
    }

    /**
     * Отримання з'єднання з БД
     *
     * @return PDO|null
     */
    private function getDB(): ?PDO
    {
        return DatabaseHelper::getConnection();
    }

    /**
     * Отримання менеджера тем через фасад (статичний метод замість глобальної функції)
     *
     * @return static
     * @phpstan-return static
     */
    public static function getManagerInstance(): self
    {
        $facadeFile = __DIR__ . '/../Facades/Theme.php';
        if (!file_exists($facadeFile)) {
            return self::getInstance();
        }

        // Завантажуємо Facade базовий клас, якщо потрібно
        if (!class_exists(\Flowaxy\Support\Facades\Facade::class, false)) {
            require_once __DIR__ . '/../Facades/Facade.php';
        }

        // Перевіряємо, чи Theme вже завантажений і чи це фасад
        $isThemeFacade = false;
        if (class_exists(\Flowaxy\Support\Facades\Theme::class, false)) {
            try {
                // Використовуємо повні імена для стандартних класів PHP
                /** @var \ReflectionClass<\Flowaxy\Support\Facades\Theme> $reflection */
                $reflection = new \ReflectionClass(\Flowaxy\Support\Facades\Theme::class);
                $isThemeFacade = $reflection->isSubclassOf(\Flowaxy\Support\Facades\Facade::class)
                    && $reflection->hasMethod('manager');
            } catch (\ReflectionException $e) {
                // Не вдалося перевірити через рефлексію - ігноруємо помилку
            }
        }

        // Якщо Theme не завантажений або це не фасад, завантажуємо фасад
        if (!$isThemeFacade) {
            require_once $facadeFile;
        }

        // Перевіряємо, чи клас Theme має метод manager та викликаємо його
        if (class_exists(\Flowaxy\Support\Facades\Theme::class, false)
            && method_exists(\Flowaxy\Support\Facades\Theme::class, 'manager')) {
            try {
                return \Flowaxy\Support\Facades\Theme::manager();
            } catch (\RuntimeException | Exception | Error $e) {
                // Контейнер не готовий або помилка - використовуємо fallback
            }
        }

        return self::getInstance();
    }
}
