<?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 preg_match_all;
use function trim;

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

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

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

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

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

        return $metadata;
    }

    /**
     * Парсинг PHPDoc комментариев из содержимого файла
     *
     * @param string $content Содержимое файла
     * @param string $pluginSlug Slug плагина (для fallback)
     * @return array<string, mixed>
     */
    private static function parsePhpDoc(string $content, string $pluginSlug): array
    {
        $metadata = [
            'slug' => $pluginSlug,
            'name' => ucfirst($pluginSlug),
            '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("PluginMetadataHelper: Found PHPDoc for {$pluginSlug}, 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',
            ];

            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'])) {
                @error_log("PluginMetadataHelper: Primary parsing failed, trying line-by-line for {$pluginSlug}");
                $lines = explode("\n", $docComment);
                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)) {
                        $tag = strtolower(trim($m[1]));
                        $val = trim($m[2]);
                        if (!empty($val) && in_array($tag, ['name', 'slug', 'version', 'author', 'author_url', 'requires', 'tested', 'package'], true)) {
                            $metadata[$tag] = $val;
                            @error_log("PluginMetadataHelper: Found {$tag} = {$val} on line {$lineNum}");
                        }
                    }
                }
            }

            @error_log("PluginMetadataHelper: Final metadata for {$pluginSlug}: " . 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;
                }
            }
        }

        return $metadata;
    }

    /**
     * Проверка существования Plugin.php файла
     *
     * @param string $pluginSlug Slug плагина
     * @return bool
     */
    public static function exists(string $pluginSlug): bool
    {
        $pluginFile = PathResolver::plugins() . DS . $pluginSlug . DS . 'Plugin.php';
        return file_exists($pluginFile) && is_readable($pluginFile);
    }
}
