<?php

/**
 * Валідатор структури теми
 *
 * Перевіряє, чи тема відповідає стандартній структурі директорій.
 *
 * @package Flowaxy\Support\Validators
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Validators;

final class ThemeStructureValidator
{
    /**
     * Стандартна структура теми
     *
     * @var array<string, array<string, mixed>>
     */
    private static array $standardStructure = [
        'required' => [
            'Theme.php' => 'Конфігураційний файл теми',
        ],
        'optional' => [
            'functions.php' => 'Функції теми',
            'hooks.php' => 'Хуки теми',
            'assets/' => 'Ресурси (CSS, JS, зображення)',
            'templates/' => 'Шаблони сторінок',
            'components/' => 'Компоненти теми',
            'layouts/' => 'Макети сторінок',
            'partials/' => 'Часткові шаблони (header, footer, sidebar)',
            'blocks/' => 'Блоки контенту',
            'snippets/' => 'Сніпети (перевикористовувані фрагменти)',
            'includes/' => 'Допоміжні файли',
            'config/' => 'Конфігурації теми',
            'lang/' => 'Файли локалізації',
            'customizer.php' => 'Файл кастомізатора теми',
        ],
    ];

    /**
     * Перевірка структури теми
     *
     * @param string $themeDir Директорія теми
     * @return array<string, mixed> Результат валідації
     */
    public static function validate(string $themeDir): array
    {
        $result = [
            'valid' => true,
            'errors' => [],
            'warnings' => [],
            'structure' => [],
        ];

        if (!is_dir($themeDir)) {
            $result['valid'] = false;
            $result['errors'][] = "Директорія теми не існує: {$themeDir}";
            return $result;
        }

        // Перевіряємо обов'язкові файли
        foreach (self::$standardStructure['required'] as $file => $description) {
            $filePath = $themeDir . DS . $file;
            if (!file_exists($filePath)) {
                // Theme.php є обов'язковим
                $result['valid'] = false;
                $result['errors'][] = "Відсутній обов'язковий файл: {$file} ({$description})";
            } else {
                $result['structure'][$file] = 'exists';
            }
        }

        // Перевіряємо опціональні директорії/файли
        foreach (self::$standardStructure['optional'] as $item => $description) {
            $itemPath = $themeDir . DS . $item;
            if (file_exists($itemPath)) {
                $result['structure'][$item] = is_dir($itemPath) ? 'directory' : 'file';
            }
        }

        return $result;
    }

    /**
     * Отримання стандартної структури
     *
     * @return array<string, array<string, mixed>>
     */
    public static function getStandardStructure(): array
    {
        return self::$standardStructure;
    }

    /**
     * Створення стандартної структури для нової теми
     *
     * @param string $themeDir Директорія теми
     * @param string $themeSlug Slug теми
     * @return bool Успіх операції
     */
    public static function createStandardStructure(string $themeDir, string $themeSlug): bool
    {
        if (!is_dir($themeDir)) {
            if (!mkdir($themeDir, 0755, true)) {
                return false;
            }
        }

        // Створюємо опціональні директорії
        $optionalDirs = array_filter(
            array_keys(self::$standardStructure['optional']),
            fn($item) => str_ends_with($item, '/')
        );

        foreach ($optionalDirs as $dir) {
            $dirPath = $themeDir . DS . trim($dir, '/');
            if (!is_dir($dirPath)) {
                mkdir($dirPath, 0755, true);
            }
        }

        // Створюємо базовий Theme.php, якщо не існує
        $themePhpPath = $themeDir . DS . 'Theme.php';
        if (!file_exists($themePhpPath)) {
            $themeName = ucfirst(str_replace('-', ' ', $themeSlug));
            $themePhpContent = "<?php\n\n/**\n * {$themeName}\n *\n * @name: {$themeName}\n * @slug: {$themeSlug}\n * @version: 1.0.0\n * @description: \n * @author: \n * @author_url: \n * @requires: 1.0.0\n * @tested: 1.0.0\n * @package: " . str_replace(' ', '', $themeName) . "\n *\n * FLOWAXY CMS 1.0.0 Stable\n */\n\ndeclare(strict_types=1);\n";
            file_put_contents($themePhpPath, $themePhpContent);
        }

        // index.php більше не потрібен - рендеринг через Theme.php

        // Створюємо базовий functions.php, якщо не існує
        $functionsPath = $themeDir . DS . 'functions.php';
        if (!file_exists($functionsPath)) {
            $functionsContent = "<?php\n\ndeclare(strict_types=1);\n\n// Функції теми {$themeSlug}\n";
            file_put_contents($functionsPath, $functionsContent);
        }

        return true;
    }

    /**
     * Отримання списку файлів теми за стандартною структурою
     *
     * @param string $themeDir Директорія теми
     * @return array<string, array<string, mixed>> Структура файлів
     */
    public static function getThemeFiles(string $themeDir): array
    {
        $files = [
            'templates' => [],
            'components' => [],
            'layouts' => [],
            'partials' => [],
            'blocks' => [],
            'snippets' => [],
            'assets' => [],
            'functions' => null,
            'hooks' => null,
            'customizer' => null,
        ];

        // Шукаємо шаблони
        $templatesDir = $themeDir . DS . 'templates';
        if (is_dir($templatesDir)) {
            $files['templates'] = glob($templatesDir . DS . '*.php');
        }

        // Шукаємо компоненти
        $componentsDir = $themeDir . DS . 'components';
        if (is_dir($componentsDir)) {
            $files['components'] = glob($componentsDir . DS . '**/*.php', GLOB_BRACE);
        }

        // Шукаємо макети
        $layoutsDir = $themeDir . DS . 'layouts';
        if (is_dir($layoutsDir)) {
            $files['layouts'] = glob($layoutsDir . DS . '*.php');
        }

        // Шукаємо часткові шаблони
        $partialsDir = $themeDir . DS . 'partials';
        if (is_dir($partialsDir)) {
            $files['partials'] = glob($partialsDir . DS . '*.php');
        }

        // Шукаємо блоки
        $blocksDir = $themeDir . DS . 'blocks';
        if (is_dir($blocksDir)) {
            $files['blocks'] = glob($blocksDir . DS . '*.php');
        }

        // Шукаємо сніпети
        $snippetsDir = $themeDir . DS . 'snippets';
        if (is_dir($snippetsDir)) {
            $files['snippets'] = glob($snippetsDir . DS . '*.php');
        }

        // Шукаємо assets
        $assetsDirs = ['assets', 'Assets'];
        foreach ($assetsDirs as $dir) {
            $assetsPath = $themeDir . DS . $dir;
            if (is_dir($assetsPath)) {
                $files['assets'] = array_merge(
                    $files['assets'],
                    glob($assetsPath . DS . '**/*', GLOB_BRACE)
                );
            }
        }

        // Шукаємо functions.php
        $functionsPath = $themeDir . DS . 'functions.php';
        if (file_exists($functionsPath)) {
            $files['functions'] = $functionsPath;
        }

        // Шукаємо hooks.php
        $hooksPath = $themeDir . DS . 'hooks.php';
        if (file_exists($hooksPath)) {
            $files['hooks'] = $hooksPath;
        }

        // Шукаємо customizer.php
        $customizerPath = $themeDir . DS . 'customizer.php';
        if (file_exists($customizerPath)) {
            $files['customizer'] = $customizerPath;
        }

        return $files;
    }
}
