<?php

declare(strict_types=1);

namespace Flowaxy\Support\Base;

use Flowaxy\Support\Containers\ThemeContainer;
use Flowaxy\Support\Helpers\DatabaseHelper;
use Flowaxy\Support\Helpers\UrlHelper;
use Flowaxy\Support\Helpers\CacheHelper;
use Flowaxy\Support\Facades\Log;
use Flowaxy\Support\Theme\Theme as ThemeAPI;
use PDO;
use Exception;
use ReflectionClass;

use function class_exists;
use function dirname;
use const DS;

// Базовий клас для всіх тем
abstract class BaseTheme
{
    protected ?array $themeData = null;
    protected ?PDO $db = null;
    protected array $config = [];
    protected ?ThemeContainer $container = null;
    protected string $themeSlug;
    protected string $themeDir;

    public function __construct(?ThemeContainer $container = null)
    {
        $this->container = $container;

        if ($container !== null) {
            $this->themeSlug = $container->getThemeSlug();
            $this->themeDir = $container->getThemeDir();
            $this->config = $container->getConfig();
        } else {
            // Fallback для зворотної сумісності
            $reflection = new ReflectionClass($this);
            $this->themeDir = dirname($reflection->getFileName()) . DS;
            $this->themeSlug = $this->getSlug();
        }

        try {
            if (class_exists(DatabaseHelper::class)) {
                $this->db = DatabaseHelper::getConnection();
            }
            $this->loadConfig();
        } catch (Exception $e) {
            Log::Error('BaseTheme constructor error: ' . $e->getMessage());
            $this->db = null;
        }
    }

    // Завантаження конфігурації теми
    private function loadConfig(): void
    {
        if (!empty($this->config)) {
            return; // Конфігурація вже завантажена з контейнера
        }

        // Читаем метаданные из Theme.php
        $themeSlug = basename(rtrim($this->themeDir, '/\\'));
        $config = \Flowaxy\Support\Helpers\ThemeMetadataHelper::readMetadata($themeSlug);
        if (!empty($config)) {
            $this->config = $config;
        }
    }

    // Ініціалізація теми (викликається при завантаженні)
    public function init(): void
    {
        // Реєструємо хуки та роути
        $this->registerHooks();
        $this->registerRoutes();

        // Перевизначається в дочірніх класах
    }

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

    // Реєстрація роутів теми
    // Перевизначається в дочірніх класах для реєстрації роутів
    public function registerRoutes(): void
    {
        // Перевизначається в дочірніх класах
    }

    /**
     * Отримати список необхідних плагінів для теми
     *
     * Може бути перевизначено в дочірніх класах або отримується з метаданих (@requires_plugins)
     *
     * @return array<string, string> Масив [plugin_slug => plugin_name]
     */
    public function getRequiredPlugins(): array
    {
        // Спочатку перевіряємо метадані
        if (isset($this->config['requires_plugins']) && is_array($this->config['requires_plugins'])) {
            return $this->config['requires_plugins'];
        }

        // Якщо в метаданих немає, повертаємо порожній масив
        return [];
    }

    // Активування теми
    // Викликається при активації теми через адмінку
    public function activate(): void
    {
        // Оновлюємо статус в контейнері
        if ($this->container !== null && method_exists($this->container, 'activate')) {
            $this->container->activate();
        }

        // Перевизначається в дочірніх класах
    }

    // Деактивування теми
    // Викликається при деактивації теми через адмінку
    public function deactivate(): void
    {
        // Оновлюємо статус в контейнері
        if ($this->container !== null && method_exists($this->container, 'deactivate')) {
            $this->container->deactivate();
        }

        // Перевизначається в дочірніх класах
    }

    // Отримання налаштувань теми з кешуванням
    public function getSettings(): array
    {
        $slug = $this->getSlug();
        $cacheKey = "theme_settings_{$slug}";

        return CacheHelper::remember($cacheKey, function () use ($slug) {
            try {
                if (class_exists(\Flowaxy\Infrastructure\Persistence\Repositories\ThemeSettingsRepository::class)) {
                    $repository = new \Flowaxy\Infrastructure\Persistence\Repositories\ThemeSettingsRepository();
                    if (method_exists($repository, 'getAll')) {
                        return $repository->getAll($slug);
                    }
                }
            } catch (\Throwable $e) {
                try {
                    Log::Error('BaseTheme getSettings помилка: ' . $e->getMessage());
                } catch (\Throwable $logError) {
                    // Ignore logging errors
                }
            }

            return [];
        }, 1800); // Кешуємо на 30 хвилин
    }

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

        try {
            if (class_exists(\Flowaxy\Domain\Theme\Services\UpdateThemeSettingsService::class)) {
                $repository = new \Flowaxy\Infrastructure\Persistence\Repositories\ThemeSettingsRepository();
                $themeRepository = new \Flowaxy\Infrastructure\Persistence\Repositories\ThemeRepository();
                $service = new \Flowaxy\Domain\Theme\Services\UpdateThemeSettingsService($repository, $themeRepository);
                $result = $service->execute($this->getSlug(), [$key => $value]);

                if ($result) {
                    // Очищаємо кеш налаштувань
                    CacheHelper::forget('theme_settings_' . $this->getSlug());
                }

                return $result;
            }
        } catch (\Throwable $e) {
            try {
                Log::Error('BaseTheme setSetting помилка: ' . $e->getMessage());
            } catch (\Throwable $logError) {
                // Ignore logging errors
            }
        }

        return false;
    }

    // Отримання налаштування теми
    public function getSetting(string $key, $default = null)
    {
        $settings = $this->getSettings();

        return $settings[$key] ?? $default;
    }

    // Отримання слагу теми
    public function getSlug(): string
    {
        if (isset($this->themeSlug)) {
            return $this->themeSlug;
        }

        return $this->config['slug'] ?? strtolower(str_replace('\\', '_', get_class($this)));
    }

    // Отримання імені теми
    public function getName(): string
    {
        return $this->config['name'] ?? get_class($this);
    }

    // Отримання версії теми
    public function getVersion(): string
    {
        return $this->config['version'] ?? '1.0.0';
    }

    // Отримання опису теми
    public function getDescription(): string
    {
        return $this->config['description'] ?? '';
    }

    // Отримання автора теми
    public function getAuthor(): string
    {
        return $this->config['author'] ?? '';
    }

    // Отримання URL теми
    public function getThemeUrl(): string
    {
        $themeDir = basename(dirname(new ReflectionClass($this)->getFileName()));
        // Використовуємо UrlHelper для отримання актуального URL з правильним протоколом
        if (class_exists(UrlHelper::class)) {
            return UrlHelper::site("/themes/{$themeDir}/");
        }
        // Fallback на константу, якщо UrlHelper не доступний
        $siteUrl = \defined('SITE_URL') ? SITE_URL : '';

        return "{$siteUrl}/themes/{$themeDir}/";
    }

    // Отримання шляху до теми
    public function getThemePath(string $filePath = ''): string
    {
        if ($this->container !== null && method_exists($this->container, 'getThemePath')) {
            return $this->container->getThemePath($filePath);
        }

        // Fallback для зворотної сумісності
        $basePath = dirname((new ReflectionClass($this))->getFileName()) . DS;

        if (empty($filePath)) {
            return $basePath;
        }

        return $basePath . ltrim($filePath, '/\\');
    }

    // Отримання контейнера теми
    public function getContainer()
    {
        return $this->container;
    }

    // Реєстрація хука
    protected function registerHook(string $hookName, callable $callback, int $priority = 10, bool $once = false): void
    {
        if (!function_exists('hooks')) {
            return;
        }

        // @phpstan-ignore-next-line - hooks() is a global function
        $hookManager = \hooks();
        $hookManager->on($hookName, $callback, $priority, $once);
    }

    // Реєстрація фільтра
    protected function registerFilter(string $hookName, callable $callback, int $priority = 10): void
    {
        if (!function_exists('hooks')) {
            return;
        }

        // @phpstan-ignore-next-line - hooks() is a global function
        $hookManager = \hooks();
        $hookManager->filter($hookName, $callback, $priority);
    }

    // Реєстрація роута теми
    protected function registerRoute($methods, string $path, $handler, array $options = []): void
    {
        if (function_exists('register_public_route')) {
            register_public_route($methods, $path, $handler, $options);
        }
    }

    // Підключення CSS файлу теми
    public function enqueueStyle(string $handle, string $file, array $dependencies = []): void
    {
        $url = ThemeAPI::asset($file);

        $this->registerHook('theme_head', function () use ($url, $handle) {
            echo "<link rel='stylesheet' id='{$handle}-css' href='{$url}' type='text/css' media='all' />\n";
        });
    }

    // Підключення JS файлу теми
    public function enqueueScript(string $handle, string $file, array $dependencies = [], bool $inFooter = true): void
    {
        $url = ThemeAPI::asset($file);

        $hookName = $inFooter ? 'theme_footer' : 'theme_head';

        $this->registerHook($hookName, function () use ($url, $handle) {
            echo "<script id='{$handle}-js' src='{$url}'></script>\n";
        });
    }

    // Отримання конфігурації теми
    public function getConfig(): array
    {
        return $this->config ?? [];
    }

    // Рендеринг шаблону теми
    public function render(string $template, array $data = [], bool $return = false)
    {
        return ThemeAPI::render($template, $data, $return);
    }

    // Рендеринг макету теми
    public function layout(string $layout, array $data = [], bool $return = false)
    {
        return ThemeAPI::layout($layout, $data, $return);
    }

    // Рендеринг компонента теми
    public function component(string $name, array $props = [], bool $return = false)
    {
        return ThemeAPI::component($name, $props, $return);
    }

    // Рендеринг partial теми
    public function partial(string $name, array $data = [], bool $return = false)
    {
        return ThemeAPI::partial($name, $data, $return);
    }
}
