<?php

declare(strict_types=1);

namespace Flowaxy\Infrastructure\Config;

use Flowaxy\Core\System\PathResolver;
use Flowaxy\Support\Facades\Log;
use Flowaxy\Support\Helpers\IniHelper;
use Throwable;

use function defined;
use function file_exists;
use function is_array;
use const DIRECTORY_SEPARATOR;
use const DS;

/**
 * Менеджер конфигурации тем
 * Управляет состоянием тем через storage/config/system/themes.ini
 */
final class ThemeConfigManager
{
    private const CONFIG_FILE = 'themes.ini';
    private const CONFIG_SECTION = 'themes';

    /**
     * Получить путь к файлу конфигурации тем
     *
     * @return string
     */
    private static function getConfigPath(): string
    {
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
        return PathResolver::storageConfig() . $ds . 'system' . $ds . self::CONFIG_FILE;
    }

    /**
     * Загрузить конфигурацию тем
     *
     * @return array<string, string>
     */
    private static function loadConfig(): array
    {
        $configPath = self::getConfigPath();

        if (!file_exists($configPath)) {
            return [];
        }

        try {
            if (class_exists(IniHelper::class)) {
                $config = IniHelper::readFile($configPath, true);
                if (is_array($config) && isset($config[self::CONFIG_SECTION]) && is_array($config[self::CONFIG_SECTION])) {
                    return $config[self::CONFIG_SECTION];
                }
            } else {
                $config = parse_ini_file($configPath, true);
                if ($config !== false && isset($config[self::CONFIG_SECTION]) && is_array($config[self::CONFIG_SECTION])) {
                    return $config[self::CONFIG_SECTION];
                }
            }
        } catch (Throwable $e) {
            try {
                Log::Error('ThemeConfigManager: Failed to load themes config', [
                    'error' => $e->getMessage(),
                    'file' => $configPath,
                ]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
        }

        return [];
    }

    /**
     * Сохранить конфигурацию тем
     *
     * @param array<string, string> $themes
     * @return bool
     */
    private static function saveConfig(array $themes): bool
    {
        $configPath = self::getConfigPath();

        // Убеждаемся, что директория существует
        $configDir = dirname($configPath);
        if (!is_dir($configDir)) {
            $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
            if (!@mkdir($configDir, 0755, true) && !is_dir($configDir)) {
                try {
                    Log::Error('ThemeConfigManager: Failed to create config directory', [
                        'dir' => $configDir,
                    ]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
                return false;
            }
        }

        try {
            $data = [self::CONFIG_SECTION => $themes];

            if (class_exists(IniHelper::class)) {
                $result = IniHelper::writeFile($configPath, $data, true);
                if ($result && file_exists($configPath)) {
                    @chmod($configPath, 0644);
                }
                return $result;
            }

            // Fallback: записываем напрямую
            $content = "; Auto-generated by Flowaxy CLI\n";
            $content .= "; Do not edit manually if you're not sure\n\n";
            $content .= "[" . self::CONFIG_SECTION . "]\n";
            foreach ($themes as $slug => $status) {
                $content .= "{$slug} = {$status}\n";
            }
            $result = @file_put_contents($configPath, $content) !== false;
            if ($result && file_exists($configPath)) {
                @chmod($configPath, 0644);
            }
            return $result;
        } catch (Throwable $e) {
            try {
                Log::Error('ThemeConfigManager: Failed to save themes config', [
                    'error' => $e->getMessage(),
                    'file' => $configPath,
                    'trace' => $e->getTraceAsString(),
                ]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    /**
     * Получить статус темы
     *
     * @param string $slug
     * @return string 'activated' | 'deactivated' | 'installed' | 'non-install'
     */
    public static function getStatus(string $slug): string
    {
        $themes = self::loadConfig();
        return $themes[$slug] ?? 'non-install';
    }

    /**
     * Установить статус темы
     *
     * @param string $slug
     * @param string $status 'activated' | 'deactivated' | 'installed' | 'non-install'
     * @return bool
     */
    public static function setStatus(string $slug, string $status): bool
    {
        if (!in_array($status, ['activated', 'deactivated', 'installed', 'non-install'], true)) {
            try {
                Log::Warning('ThemeConfigManager: Invalid status', [
                    'slug' => $slug,
                    'status' => $status,
                ]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }

        $themes = self::loadConfig();

        // Если активируем тему, деактивируем все остальные
        if ($status === 'activated') {
            foreach ($themes as $key => $value) {
                if ($value === 'activated' && $key !== $slug) {
                    $themes[$key] = 'deactivated';
                }
            }
        }

        $themes[$slug] = $status;
        return self::saveConfig($themes);
    }

    /**
     * Проверить, установлена ли тема
     *
     * @param string $slug
     * @return bool
     */
    public static function isInstalled(string $slug): bool
    {
        $status = self::getStatus($slug);
        return $status !== 'non-install';
    }

    /**
     * Проверить, активна ли тема
     *
     * @param string $slug
     * @return bool
     */
    public static function isActive(string $slug): bool
    {
        return self::getStatus($slug) === 'activated';
    }

    /**
     * Получить активную тему
     *
     * @return string|null
     */
    public static function getActive(): ?string
    {
        $themes = self::loadConfig();
        foreach ($themes as $slug => $status) {
            if ($status === 'activated') {
                return $slug;
            }
        }
        return null;
    }

    /**
     * Получить все темы
     *
     * @return array<string, string>
     */
    public static function getAll(): array
    {
        return self::loadConfig();
    }

    /**
     * Удалить тему из конфигурации
     *
     * @param string $slug
     * @return bool
     */
    public static function remove(string $slug): bool
    {
        $themes = self::loadConfig();
        if (isset($themes[$slug])) {
            unset($themes[$slug]);
            return self::saveConfig($themes);
        }
        return true;
    }
}
