<?php

declare(strict_types=1);

namespace Flowaxy\Support\Helpers;

use Flowaxy\Core\System\PathResolver;

use function file_exists;
use function file_get_contents;
use function is_readable;
use function preg_match;
use function trim;

/**
 * Хелпер для чтения метаданных темы из Theme.php (PHPDoc комментарии)
 */
final class ThemeMetadataHelper
{
    /**
     * Чтение метаданных темы из Theme.php
     *
     * @param string $themeSlug Slug темы
     * @return array<string, mixed>
     */
    public static function readMetadata(string $themeSlug): array
    {
        $themeFile = PathResolver::themes() . DS . $themeSlug . DS . 'Theme.php';

        if (!file_exists($themeFile) || !is_readable($themeFile)) {
            @error_log("ThemeMetadataHelper: File not found or not readable - slug: {$themeSlug}, file: {$themeFile}");
            return [];
        }

        $content = @file_get_contents($themeFile);
        if ($content === false) {
            @error_log("ThemeMetadataHelper: Failed to read file - slug: {$themeSlug}, file: {$themeFile}");
            return [];
        }

        $metadata = self::parsePhpDoc($content, $themeSlug);

        // Логируем результат парсинга для отладки через error_log
        @error_log("ThemeMetadataHelper: Parsed metadata for {$themeSlug}: " . json_encode($metadata, JSON_UNESCAPED_UNICODE));

        return $metadata;
    }

    /**
     * Парсинг PHPDoc комментариев из содержимого файла
     *
     * @param string $content Содержимое файла
     * @param string $themeSlug Slug темы (для fallback)
     * @return array<string, mixed>
     */
    private static function parsePhpDoc(string $content, string $themeSlug): array
    {
        $metadata = [
            'slug' => $themeSlug,
            'name' => ucfirst($themeSlug),
            'version' => '1.0.0',
            'description' => '',
            'author' => '',
            'author_url' => '',
            'requires' => '1.0.0',
            'tested' => '1.0.0',
        ];

        // Ищем PHPDoc комментарий в начале файла
        // Паттерн ищет /** ... */ с учетом многострочности и звездочек в начале строк
        // Более гибкий паттерн, который работает с разными форматами PHPDoc
        if (preg_match('/\/\*\*\s*(.*?)\s*\*\//s', $content, $matches)) {
            $docComment = $matches[0];
            @error_log("ThemeMetadataHelper: Found PHPDoc for {$themeSlug}, length: " . strlen($docComment));

            // Парсим отдельные аннотации с учетом формата @tag: value
            // Ищем паттерн @tag: value, учитывая что может быть звездочка в начале строки
            // Формат: " * @tag: value" или "@tag: value"
            // Более гибкий паттерн, который работает с многострочными значениями
            $patterns = [
                '/@name:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'name',
                '/@slug:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'slug',
                '/@version:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'version',
                '/@description:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'description',
                '/@author:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'author',
                '/@author_url:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'author_url',
                '/@requires:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'requires',
                '/@tested:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'tested',
                '/@package:\s*([^\n\*@]+?)(?=\s*\*\/|\s*\*?\s*@|\s*$)/is' => 'package',
                // requires_plugins не парсим здесь, так как может быть длинной строкой - обрабатываем отдельно
            ];

            foreach ($patterns as $pattern => $key) {
                if (preg_match($pattern, $docComment, $matches)) {
                    $value = trim($matches[1]);
                    // Убираем звездочки и пробелы в начале строк
                    $value = preg_replace('/^\s*\*\s*/m', '', $value);
                    $value = preg_replace('/\s+/', ' ', $value); // Нормализуем пробелы
                    $value = trim($value);
                    if (!empty($value)) {
                        $metadata[$key] = $value;
                    }
                }
            }

            // Альтернативный способ парсинга - построчно (если основной не сработал)
            if (empty($metadata['name']) || empty($metadata['slug']) || !isset($metadata['requires_plugins'])) {
                @error_log("ThemeMetadataHelper: Primary parsing incomplete, trying line-by-line for {$themeSlug}");
                $lines = explode("\n", $docComment);
                $currentTag = null;
                $currentValue = '';
                foreach ($lines as $lineNum => $line) {
                    $originalLine = $line;
                    $line = trim($line);
                    // Убираем звездочки и пробелы
                    $line = preg_replace('/^\s*\*\s*/', '', $line);
                    $line = trim($line);

                    // Парсим @tag: value
                    if (preg_match('/^@(\w+):\s*(.+)$/i', $line, $m)) {
                        // Сохраняем предыдущий тег, если он был
                        if ($currentTag === 'requires_plugins' && !empty($currentValue)) {
                            $metadata['requires_plugins'] = trim($currentValue);
                        }

                        $tag = strtolower(trim($m[1]));
                        $val = trim($m[2]);
                        if (!empty($val) && in_array($tag, ['name', 'slug', 'version', 'author', 'author_url', 'requires', 'tested', 'package', 'requires_plugins'], true)) {
                            if ($tag === 'requires_plugins') {
                                $currentTag = 'requires_plugins';
                                $currentValue = $val;
                            } else {
                                $metadata[$tag] = $val;
                                $currentTag = null;
                                $currentValue = '';
                            }
                            @error_log("ThemeMetadataHelper: Found {$tag} = {$val} on line {$lineNum}");
                        }
                    } elseif ($currentTag === 'requires_plugins' && !empty($line)) {
                        // Продолжаем собирать значение для requires_plugins
                        $currentValue .= ' ' . $line;
                    }
                }

                // Сохраняем последний requires_plugins, если был
                if ($currentTag === 'requires_plugins' && !empty($currentValue)) {
                    $metadata['requires_plugins'] = trim($currentValue);
                }
            }

            @error_log("ThemeMetadataHelper: Final metadata for {$themeSlug}: " . json_encode($metadata, JSON_UNESCAPED_UNICODE));

            // Парсим многострочные описания (может быть на нескольких строках)
            if (preg_match('/@description:\s*((?:[^*@]|\*(?!\/))+(?:\s*\*[^*@]*)*)/is', $docComment, $matches)) {
                $description = trim($matches[1]);
                $description = preg_replace('/^\s*\*\s*/m', '', $description);
                $description = preg_replace('/\n\s*\*\s*/', ' ', $description);
                $description = preg_replace('/\s+/', ' ', $description); // Нормализуем пробелы
                $description = trim($description);
                if (!empty($description)) {
                    $metadata['description'] = $description;
                }
            }

            // Парсим requires_plugins (список плагинов через запятую: plugin-slug1:Plugin Name1, plugin-slug2:Plugin Name2)
            // Преобразуем строку в массив, если она есть
            if (isset($metadata['requires_plugins']) && is_string($metadata['requires_plugins'])) {
                $pluginsString = trim($metadata['requires_plugins']);
                if (!empty($pluginsString)) {
                    // Преобразуем строку в массив
                    $pluginsList = [];
                    // Разбиваем по запятой
                    $plugins = explode(',', $pluginsString);
                    foreach ($plugins as $plugin) {
                        $plugin = trim($plugin);
                        if (empty($plugin)) {
                            continue;
                        }
                        // Формат: plugin-slug:Plugin Name или просто plugin-slug
                        if (str_contains($plugin, ':')) {
                            [$slug, $name] = explode(':', $plugin, 2);
                            $pluginsList[trim($slug)] = trim($name);
                        } else {
                            // Если имя не указано, используем slug с заглавной буквы
                            $pluginsList[$plugin] = ucfirst(str_replace('-', ' ', $plugin));
                        }
                    }
                    if (!empty($pluginsList)) {
                        $metadata['requires_plugins'] = $pluginsList;
                    } else {
                        unset($metadata['requires_plugins']);
                    }
                } else {
                    unset($metadata['requires_plugins']);
                }
            }
        }

        return $metadata;
    }

    /**
     * Проверка существования Theme.php файла
     *
     * @param string $themeSlug Slug темы
     * @return bool
     */
    public static function exists(string $themeSlug): bool
    {
        $themeFile = PathResolver::themes() . DS . $themeSlug . DS . 'Theme.php';
        return file_exists($themeFile) && is_readable($themeFile);
    }
}
