<?php

declare(strict_types=1);

namespace Flowaxy\Infrastructure\Persistence\Repositories;

use Flowaxy\Core\System\PathResolver;
use Flowaxy\Domain\Theme\Entities\Theme as ThemeEntity;
use Flowaxy\Domain\Theme\Services\ThemeRepositoryInterface;
use Flowaxy\Infrastructure\Persistence\Database\Database;
use Flowaxy\Support\Facades\Log;
use Flowaxy\Support\Helpers\CacheHelper;
use Flowaxy\Support\Helpers\DatabaseHelper;
use PDO;
use PDOException;
use Throwable;

use function array_filter;
use function basename;
use function glob;
use function is_array;
use function realpath;
use function ucfirst;
use const DS;
use const GLOB_ONLYDIR;

final class ThemeRepository implements ThemeRepositoryInterface
{
    private ?PDO $connection;
    private string $themesDir;

    public function __construct()
    {
        // Используем DatabaseHelper для получения соединения
        $this->connection = DatabaseHelper::getConnection();

        $dir = PathResolver::themes();
        $this->themesDir = realpath($dir) ? realpath($dir) . DS : $dir;
    }

    /**
     * @return array<int, ThemeEntity>
     */
    public function all(): array
    {
        $directories = glob($this->themesDir . '*', GLOB_ONLYDIR) ?: [];
        $themes = [];

        foreach ($directories as $dir) {
            $slug = basename($dir);
            $config = $this->loadThemeConfig($slug);

            $themes[] = new ThemeEntity(
                slug: $config['slug'] ?? $slug,
                name: $config['name'] ?? ucfirst($slug),
                version: $config['version'] ?? '1.0.0',
                description: $config['description'] ?? '',
                active: $this->isActive($slug),
                supportsCustomization: (bool)($config['supports_customization'] ?? false),
                meta: $config
            );
        }

        return $themes;
    }

    public function find(string $slug): ?ThemeEntity
    {
        foreach ($this->all() as $theme) {
            if ($theme->slug === $slug) {
                return $theme;
            }
        }

        return null;
    }

    public function getActive(): ?ThemeEntity
    {
        $slug = $this->fetchActiveSlug();

        return $slug ? $this->find($slug) : null;
    }

    public function activate(string $slug): bool
    {
        if (! $this->themeExists($slug)) {
            return false;
        }

        try {
            if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                $result = \Flowaxy\Infrastructure\Config\ThemeConfigManager::setStatus($slug, 'activated');
                if ($result) {
                    $this->flushThemeCache($slug);
                }
                return $result;
            }
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка активації теми', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
        }

        return false;
    }

    public function deactivate(string $slug): bool
    {
        try {
            if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                $result = \Flowaxy\Infrastructure\Config\ThemeConfigManager::setStatus($slug, 'deactivated');
                if ($result) {
                    $this->flushThemeCache($slug);
                }
                return $result;
            }
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка деактивації теми', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
        }

        return false;
    }

    /**
     * @return array<string, mixed>
     */
    /**
     * @return array<string, mixed>
     */
    private function loadThemeConfig(string $slug): array
    {
        // Используем ThemeMetadataHelper для чтения метаданных из Theme.php
        if (class_exists(\Flowaxy\Support\Helpers\ThemeMetadataHelper::class)) {
            $config = \Flowaxy\Support\Helpers\ThemeMetadataHelper::readMetadata($slug);
            if (is_array($config) && !empty($config)) {
                if (empty($config['slug'])) {
                    $config['slug'] = $slug;
                }
                return $config;
            }
        }

        return ['slug' => $slug];
    }

    private function themeExists(string $slug): bool
    {
        return is_dir($this->themesDir . $slug);
    }

    private function isActive(string $slug): bool
    {
        $active = $this->fetchActiveSlug();

        return $active !== null && $active === $slug;
    }

    private function fetchActiveSlug(): ?string
    {
        try {
            if (class_exists(\Flowaxy\Infrastructure\Config\ThemeConfigManager::class)) {
                return \Flowaxy\Infrastructure\Config\ThemeConfigManager::getActive();
            }
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка отримання активної теми', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
        }

        return null;
    }

    private function flushThemeCache(?string $slug = null): void
    {
        $keysToForget = ['active_theme_slug', 'active_theme', 'all_themes_filesystem'];

        if ($slug) {
            $keysToForget[] = 'theme_settings_' . $slug;
            $keysToForget[] = 'theme_config_' . $slug;
            $keysToForget[] = 'theme_' . $slug;
        }

        CacheHelper::forgetMultiple($keysToForget);
    }
}
