<?php

/**
 * Страница управления плагинами (функция вместо класса)
 *
 * Примечание: Авторизация обрабатывается автоматически через middleware 'admin.auth'
 * Разработчикам не нужно проверять авторизацию вручную - фреймворк делает это автоматически
 */

function admin_plugins_page()
{
    // Обработка POST запросов (действия с плагинами)
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['action'])) {
        handle_plugin_action();
        // Редирект после обработки действия
        if (function_exists('admin_redirect')) {
            admin_redirect('plugins');
        } else {
            header('Location: ' . admin_url('plugins'));
        }
        exit;
    }

    // Обработка AJAX запросов
    if (
        !empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
        strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'
    ) {
        handle_plugins_ajax();
        return;
    }

    // Получаем данные плагинов через хуки
    $data = get_content_data('plugins_data', [
        'plugins' => get_plugins_list(),
    ]);

    // Создаем кнопку "Загрузить плагин"
    $uploadButton = '';
    if (file_exists(__DIR__ . DS . '..' . DS . 'components' . DS . 'button' . DS . 'button.php')) {
        ob_start();
        $text = 'Завантажити плагін';
        $type = 'primary';
        $icon = 'upload';
        $attributes = [
            'data-bs-toggle' => 'modal',
            'data-bs-target' => '#uploadPluginModal',
            'onclick' => 'window.ModalHandler && window.ModalHandler.show("uploadPluginModal")',
        ];
        include __DIR__ . DS . '..' . DS . 'components' . DS . 'button' . DS . 'button.php';
        $uploadButton = ob_get_clean();
    } else {
        // Fallback кнопка
        $uploadButton = '<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadPluginModal">
            <i class="fas fa-upload"></i> Завантажити плагін
        </button>';
    }

    $layout = [
        'title' => 'Керування плагінами - Flowaxy CMS',
        'content' => render_plugins_content($data),
        'pageHeaderIcon' => 'fas fa-puzzle-piece',
        'pageHeaderButtons' => $uploadButton,
        'pageBreadcrumbs' => [
            ['title' => 'Головна', 'url' => admin_url('dashboard'), 'page' => 'dashboard'],
            ['title' => 'Керування плагінами', 'page' => 'plugins'],
        ],
        'additionalJS' => [
            asset('scripts/plugins.js'),
        ],
    ];

    return render_admin_layout($layout);
}

function render_plugins_content($data)
{
    ob_start();
    $templatePath = __DIR__ . DS . 'plugins' . DS . 'template.php';
    if (file_exists($templatePath)) {
        // Определяем путь к компонентам
        $componentsPath = __DIR__ . DS . '..' . DS . 'components' . DS;

        // Получаем список плагинов и статистику
        $plugins = $data['plugins'] ?? [];
        $installedPlugins = [];
        $stats = [
            'total' => 0,
            'installed' => 0,
            'active' => 0,
            'inactive' => 0,
        ];

        if (is_array($plugins) && !empty($plugins)) {
            $stats['total'] = count($plugins);
            foreach ($plugins as $pluginSlug => $plugin) {
                if (is_array($plugin)) {
                    // Убеждаемся, что slug есть в массиве плагина
                    if (empty($plugin['slug'])) {
                        $plugin['slug'] = $pluginSlug;
                    }

                    // Получаем статус из конфигурации (или из самого плагина, если он уже есть)
                    $currentSlug = $plugin['slug'] ?? $pluginSlug;
                    $status = $plugin['status'] ?? 'Non-install';

                    if (!empty($currentSlug) && $status === 'Non-install') {
                        try {
                            if (!class_exists(\Flowaxy\Infrastructure\Config\PluginConfigManager::class, false)) {
                                \Flowaxy\Support\Helpers\ClassLoaderHelper::ensureLoaded(\Flowaxy\Infrastructure\Config\PluginConfigManager::class);
                            }
                            $status = \Flowaxy\Infrastructure\Config\PluginConfigManager::getStatus($currentSlug);
                            $plugin['status'] = $status;
                        } catch (\Throwable $e) {
                            $status = 'Non-install';
                            $plugin['status'] = $status;
                        }
                    }

                    // Добавляем статусы для компонента plugin-card
                    $plugin['is_active'] = ($status === 'active');
                    $plugin['is_installed'] = ($status !== 'Non-install');

                    // Проверяем наличие миграций (требует БД)
                    $pluginDir = \Flowaxy\Core\System\PathResolver::plugins() . \DS . $currentSlug;
                    $migrationsDir = $pluginDir . \DS . 'migrations';
                    $dbDir = $pluginDir . \DS . 'db';
                    $plugin['requires_database'] = (
                        (is_dir($migrationsDir) && count(glob($migrationsDir . \DS . '*.php')) > 0) ||
                        (is_dir($dbDir) && (file_exists($dbDir . \DS . 'install.sql') || count(glob($dbDir . \DS . '*.sql')) > 0))
                    );

                    // Все плагины отображаются (включая Non-install)
                    $installedPlugins[] = $plugin;

                    // Подсчитываем статистику
                    if ($status !== 'Non-install') {
                        $stats['installed']++;
                        if ($status === 'active') {
                            $stats['active']++;
                        } else {
                            $stats['inactive']++;
                        }
                    } else {
                        // Плагин обнаружен, но не установлен
                        $stats['inactive']++;
                    }
                }
            }
        }

        $data['componentsPath'] = $componentsPath;
        $data['installedPlugins'] = $installedPlugins;
        $data['stats'] = $stats;

        extract($data);
        include $templatePath;
    }
    return ob_get_clean();
}

function get_plugins_list()
{
    $plugins = [];
    try {
        if (function_exists('pluginManager')) {
            $pluginManager = pluginManager();
            if ($pluginManager && method_exists($pluginManager, 'getAllPlugins')) {
                $plugins = $pluginManager->getAllPlugins();

                // Логируем результат для отладки
                if (function_exists('error_log')) {
                    error_log('get_plugins_list: Found ' . count($plugins) . ' plugins: ' . implode(', ', array_keys($plugins)));
                }

                // Если это ассоциативный массив, преобразуем в список
                if (!empty($plugins) && is_array($plugins)) {
                    // getAllPlugins возвращает массив где ключи - это slug плагинов
                    // Оставляем как есть, но убеждаемся что slug есть в каждом элементе
                    foreach ($plugins as $slug => &$plugin) {
                        if (is_array($plugin) && empty($plugin['slug'])) {
                            $plugin['slug'] = $slug;
                        }
                    }
                    unset($plugin);
                }
            } else {
                if (function_exists('error_log')) {
                    error_log('get_plugins_list: pluginManager() returned null or getAllPlugins method not found');
                }
            }
        } else {
            if (function_exists('error_log')) {
                error_log('get_plugins_list: pluginManager function not found');
            }
        }
    } catch (\Throwable $e) {
        // Логируем ошибку, но не показываем пользователю
        if (function_exists('error_log')) {
            error_log('get_plugins_list error: ' . $e->getMessage() . ' | Trace: ' . $e->getTraceAsString());
        }
    }
    return $plugins;
}

function handle_plugin_action()
{
    // Проверка CSRF токена
    if (!function_exists('verify_csrf_token') || !verify_csrf_token()) {
        if (function_exists('set_flash_message')) {
            set_flash_message('Помилка безпеки', 'danger');
        }
        return;
    }

    // Проверка прав доступа
    if (!function_exists('current_user_can') || !current_user_can('admin.access')) {
        if (function_exists('set_flash_message')) {
            set_flash_message('У вас немає прав на виконання цієї дії', 'danger');
        }
        return;
    }

    $action = $_POST['action'] ?? '';
    $pluginSlug = $_POST['plugin_slug'] ?? '';

    // Для upload_plugin не требуется pluginSlug
    if (empty($action)) {
        if (function_exists('set_flash_message')) {
            set_flash_message('Не вказано дію', 'danger');
        }
        return;
    }

    // Для всех действий кроме upload_plugin требуется pluginSlug
    if ($action !== 'upload_plugin' && empty($pluginSlug)) {
        if (function_exists('set_flash_message')) {
            set_flash_message('Не вказано slug плагіна', 'danger');
        }
        return;
    }

    try {
        if (!function_exists('pluginManager')) {
            if (function_exists('set_flash_message')) {
                set_flash_message('PluginManager недоступний', 'danger');
            }
            return;
        }

        $pluginManager = pluginManager();
        if (!$pluginManager) {
            if (function_exists('set_flash_message')) {
                set_flash_message('PluginManager недоступний', 'danger');
            }
            return;
        }

        switch ($action) {
            case 'install':
                // Устанавливаем плагин через PluginManager для правильного жизненного цикла
                $result = $pluginManager->installPlugin($pluginSlug);
                if ($result) {
                    if (function_exists('set_flash_message')) {
                        set_flash_message('Плагін встановлено', 'success');
                    }
                } else {
                    // Отримуємо детальну помилку, якщо доступна
                    $errorMessage = 'Помилка встановлення плагіна';
                    if (method_exists($pluginManager, 'getLastInstallError')) {
                        $lastError = $pluginManager->getLastInstallError();
                        if (!empty($lastError)) {
                            $errorMessage = $lastError;
                        }
                    }
                    if (function_exists('set_flash_message')) {
                        set_flash_message($errorMessage, 'danger');
                    }
                }
                break;

            case 'activate':
            case 'activate_plugin':
                // Активируем плагин через PluginManager для правильного жизненного цикла
                $result = $pluginManager->activatePlugin($pluginSlug);
                if ($result) {
                    if (function_exists('set_flash_message')) {
                        set_flash_message('Плагін активовано', 'success');
                    } elseif (function_exists('set_message')) {
                        set_message('Плагін активовано', 'success');
                    }
                } else {
                    if (function_exists('set_flash_message')) {
                        set_flash_message('Помилка активації плагіна', 'danger');
                    } elseif (function_exists('set_message')) {
                        set_message('Помилка активації плагіна', 'danger');
                    }
                }
                break;

            case 'deactivate':
            case 'deactivate_plugin':
                // Деактивируем плагин через PluginManager для правильного жизненного цикла
                $result = $pluginManager->deactivatePlugin($pluginSlug);
                if ($result) {
                    if (function_exists('set_flash_message')) {
                        set_flash_message('Плагін деактивовано', 'success');
                    } elseif (function_exists('set_message')) {
                        set_message('Плагін деактивовано', 'success');
                    }
                } else {
                    if (function_exists('set_flash_message')) {
                        set_flash_message('Помилка деактивації плагіна', 'danger');
                    } elseif (function_exists('set_message')) {
                        set_message('Помилка деактивації плагіна', 'danger');
                    }
                }
                break;

            case 'uninstall':
                // Проверяем, что плагин деактивирован перед удалением
                if (!class_exists(\Flowaxy\Infrastructure\Config\PluginConfigManager::class, false)) {
                    \Flowaxy\Support\Helpers\ClassLoaderHelper::ensureLoaded(\Flowaxy\Infrastructure\Config\PluginConfigManager::class);
                }
                $status = \Flowaxy\Infrastructure\Config\PluginConfigManager::getStatus($pluginSlug);
                if ($status === 'active') {
                    if (function_exists('set_flash_message')) {
                        set_flash_message('Спочатку деактивуйте плагін перед видаленням', 'warning');
                    } elseif (function_exists('set_message')) {
                        set_message('Спочатку деактивуйте плагін перед видаленням', 'warning');
                    }
                    return;
                }
                // Получаем имя плагина ДО удаления для более информативного сообщения
                $pluginName = $pluginSlug;
                try {
                    if (class_exists('\Flowaxy\Support\Helpers\PluginMetadataHelper')) {
                        $metadata = \Flowaxy\Support\Helpers\PluginMetadataHelper::readMetadata($pluginSlug);
                        if (!empty($metadata['name'])) {
                            $pluginName = $metadata['name'];
                        }
                    }
                } catch (\Throwable $e) {
                    // Игнорируем ошибки получения метаданных
                }

                // Удаляем плагин через PluginManager для правильного жизненного цикла
                $result = $pluginManager->uninstallPlugin($pluginSlug);
                if ($result) {
                    $message = "Плагін <strong>{$pluginName}</strong> успішно видалено";
                    if (function_exists('set_flash_message')) {
                        set_flash_message($message, 'success');
                    } elseif (function_exists('set_message')) {
                        set_message($message, 'success');
                    }
                } else {
                    if (function_exists('set_flash_message')) {
                        set_flash_message('Помилка видалення плагіна', 'danger');
                    } elseif (function_exists('set_message')) {
                        set_message('Помилка видалення плагіна', 'danger');
                    }
                }
                break;

            case 'upload_plugin':
                // Обработка загрузки плагина из ZIP-архива
                handle_plugin_upload();
                break;

            default:
                if (function_exists('set_flash_message')) {
                    set_flash_message('Невідома дія', 'danger');
                }
        }
    } catch (\Throwable $e) {
        if (function_exists('error_log')) {
            error_log('handle_plugin_action error: ' . $e->getMessage() . ' | Trace: ' . $e->getTraceAsString());
        }
        if (function_exists('set_flash_message')) {
            set_flash_message('Помилка: ' . $e->getMessage(), 'danger');
        }
    }
}

function handle_plugin_upload()
{
    // Проверка наличия загруженных файлов
    if (empty($_FILES['plugin_file']) || !is_array($_FILES['plugin_file']['name'])) {
        if (function_exists('set_flash_message')) {
            set_flash_message('Файли не вибрано', 'danger');
        }
        return;
    }

    // Загружаем необходимые классы
    if (!class_exists(\Flowaxy\Support\Services\FileUploadService::class, false)) {
        \Flowaxy\Support\Helpers\ClassLoaderHelper::ensureLoaded(\Flowaxy\Support\Services\FileUploadService::class);
    }
    if (!class_exists(\Flowaxy\Support\Services\ArchiveExtractionService::class, false)) {
        \Flowaxy\Support\Helpers\ClassLoaderHelper::ensureLoaded(\Flowaxy\Support\Services\ArchiveExtractionService::class);
    }
    if (!class_exists(\Flowaxy\Core\System\PathResolver::class, false)) {
        \Flowaxy\Support\Helpers\ClassLoaderHelper::ensureLoaded(\Flowaxy\Core\System\PathResolver::class);
    }

    $uploadService = new \Flowaxy\Support\Services\FileUploadService();
    $archiveService = new \Flowaxy\Support\Services\ArchiveExtractionService();
    $pluginsDir = \Flowaxy\Core\System\PathResolver::plugins();

    $uploadedCount = 0;
    $errors = [];
    $installedPlugins = []; // Список успешно загруженных плагинов

    // Обрабатываем каждый загруженный файл
    $files = $_FILES['plugin_file'];
    $fileCount = count($files['name']);

    for ($i = 0; $i < $fileCount; $i++) {
        // Формируем массив файла для обработки
        $file = [
            'name' => $files['name'][$i],
            'type' => $files['type'][$i],
            'tmp_name' => $files['tmp_name'][$i],
            'error' => $files['error'][$i],
            'size' => $files['size'][$i],
        ];

        // Пропускаем файлы с ошибками
        if ($file['error'] !== UPLOAD_ERR_OK) {
            $errors[] = "Файл '{$file['name']}': помилка завантаження (код: {$file['error']})";
            continue;
        }

        try {
            // Загружаем файл во временную директорию
            $uploadResult = $uploadService->upload($file, [
                'allowed_extensions' => ['zip'],
                'allowed_mime_types' => ['application/zip', 'application/x-zip-compressed'],
                'max_file_size' => 50 * 1024 * 1024, // 50 MB
            ]);

            if (!$uploadResult['success']) {
                $errors[] = "Файл '{$file['name']}': " . ($uploadResult['error'] ?? 'Помилка завантаження');
                continue;
            }

            $uploadedFile = $uploadResult['file'] ?? null;
            if (!$uploadedFile || !file_exists($uploadedFile)) {
                $errors[] = "Файл '{$file['name']}': файл не знайдено після завантаження";
                continue;
            }

            // Сначала валидируем архив и получаем slug
            // Пробуем с Plugin.php (с большой буквы)
            $zip = \Flowaxy\Support\Facades\Archive::open($uploadedFile, \ZipArchive::RDONLY);
            $validation = $archiveService->validateArchive($zip, 'Plugin.php');
            $zip->close();

            // Если не нашли Plugin.php, пробуем plugin.php (с маленькой буквы)
            if (!$validation['valid'] && str_contains($validation['error'] ?? '', 'не містить')) {
                $zip = \Flowaxy\Support\Facades\Archive::open($uploadedFile, \ZipArchive::RDONLY);
                if ($zip) {
                    $validation = $archiveService->validateArchive($zip, 'plugin.php');
                    $zip->close();
                }
            }

            if (!$validation['valid']) {
                $errors[] = "Файл '{$file['name']}': " . ($validation['error'] ?? 'Архів не валідний');
                // Очищаем загруженный файл
                if ($uploadedFile && file_exists($uploadedFile)) {
                    \Flowaxy\Support\Helpers\ResourceCleanupHelper::cleanupTempFiles($uploadedFile);
                }
                continue;
            }

            $slug = $validation['slug'] ?? null;
            if (empty($slug)) {
                $errors[] = "Файл '{$file['name']}': неможливо визначити slug плагіна";
                // Очищаем загруженный файл
                if ($uploadedFile && file_exists($uploadedFile)) {
                    \Flowaxy\Support\Helpers\ResourceCleanupHelper::cleanupTempFiles($uploadedFile);
                }
                continue;
            }

            // Определяем путь назначения для плагина
            $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
            $pluginDestinationPath = $pluginsDir . $ds . $slug;

            // Извлекаем архив в директорию плагина
            // Пробуем с Plugin.php (с большой буквы)
            $extractionResult = $archiveService->extractZip(
                $uploadedFile,
                $pluginDestinationPath,
                'Plugin.php',
                false // не перезаписывать существующие плагины
            );

            // Если не нашли Plugin.php, пробуем plugin.php (с маленькой буквы)
            if (!$extractionResult['success'] && str_contains($extractionResult['error'] ?? '', 'не містить')) {
                $extractionResult = $archiveService->extractZip(
                    $uploadedFile,
                    $pluginDestinationPath,
                    'plugin.php',
                    false
                );
            }

            // Очищаем загруженный файл
            if ($uploadedFile && file_exists($uploadedFile)) {
                \Flowaxy\Support\Helpers\ResourceCleanupHelper::cleanupTempFiles($uploadedFile);
            }

            if (!$extractionResult['success']) {
                $errors[] = "Файл '{$file['name']}': " . ($extractionResult['error'] ?? 'Помилка витягування архіву');
                continue;
            }

            $slug = $extractionResult['slug'] ?? null;
            if (empty($slug)) {
                $errors[] = "Файл '{$file['name']}': неможливо визначити slug плагіна";
                continue;
            }

            // Плагин успешно загружен и извлечен, но не устанавливается автоматически
            // Пользователь должен установить его вручную через интерфейс
            $uploadedCount++;
            $installedPlugins[] = $slug; // Сохраняем slug загруженного плагина
            try {
                if (class_exists('\Flowaxy\Support\Facades\Log')) {
                    \Flowaxy\Support\Facades\Log::Info('Плагін завантажено', [
                        'slug' => $slug,
                        'file' => $file['name'],
                    ]);
                }
            } catch (\Throwable $logError) {
                // Ignore logging errors
            }
        } catch (\Throwable $e) {
            $errors[] = "Файл '{$file['name']}': " . $e->getMessage();
            try {
                if (class_exists('\Flowaxy\Support\Facades\Log')) {
                    \Flowaxy\Support\Facades\Log::Error('Помилка завантаження плагіна', [
                        'file' => $file['name'],
                        'exception' => $e,
                    ]);
                }
            } catch (\Throwable $logError) {
                // Ignore logging errors
            }
        }
    }

    // Формируем детальные сообщения о результате
    $successMessages = [];
    $errorMessages = $errors;

    // Собираем информацию о успешно загруженных плагинах
    if ($uploadedCount > 0 && !empty($installedPlugins)) {
        if ($uploadedCount === 1) {
            $pluginName = $installedPlugins[0];
            // Пытаемся получить имя плагина из метаданных
            try {
                if (class_exists('\Flowaxy\Support\Helpers\PluginMetadataHelper')) {
                    $metadata = \Flowaxy\Support\Helpers\PluginMetadataHelper::readMetadata($pluginName);
                    if (!empty($metadata['name'])) {
                        $pluginName = $metadata['name'];
                    }
                }
            } catch (\Throwable $e) {
                // Игнорируем ошибки получения метаданных
            }
            $successMessages[] = "Плагін <strong>{$pluginName}</strong> успішно завантажено. Тепер ви можете встановити його вручну.";
        } else {
            $pluginsList = [];
            foreach ($installedPlugins as $slug) {
                try {
                    if (class_exists('\Flowaxy\Support\Helpers\PluginMetadataHelper')) {
                        $metadata = \Flowaxy\Support\Helpers\PluginMetadataHelper::readMetadata($slug);
                        $pluginsList[] = $metadata['name'] ?? $slug;
                    } else {
                        $pluginsList[] = $slug;
                    }
                } catch (\Throwable $e) {
                    $pluginsList[] = $slug;
                }
            }
            $pluginsListStr = implode(', ', array_slice($pluginsList, 0, 3));
            if (count($pluginsList) > 3) {
                $pluginsListStr .= ' та ще ' . (count($pluginsList) - 3) . ' плагінів';
            }
            $successMessages[] = "Завантажено <strong>{$uploadedCount}</strong> плагінів: {$pluginsListStr}. Тепер ви можете встановити їх вручну.";
        }
    }

    // Формируем итоговое сообщение
    if ($uploadedCount > 0) {
        $message = implode('. ', $successMessages);
        if (!empty($errorMessages)) {
            $message .= '<br><br><strong>Помилки:</strong><br>' . implode('<br>', array_slice($errorMessages, 0, 3)); // Показываем максимум 3 ошибки
            if (count($errorMessages) > 3) {
                $message .= '<br><em>і ще ' . (count($errorMessages) - 3) . ' помилок</em>';
            }
        }

        $messageType = empty($errorMessages) ? 'success' : 'warning';
        if (function_exists('set_flash_message')) {
            set_flash_message($message, $messageType);
        }
    } else {
        // Все файлы не удалось обработать
        $errorMessage = !empty($errorMessages)
            ? '<strong>Помилки завантаження:</strong><br>' . implode('<br>', array_slice($errorMessages, 0, 3))
            : 'Помилка завантаження плагінів';

        if (count($errorMessages) > 3) {
            $errorMessage .= '<br><em>і ще ' . (count($errorMessages) - 3) . ' помилок</em>';
        }

        if (function_exists('set_flash_message')) {
            set_flash_message($errorMessage, 'danger');
        }
    }
}

function handle_plugins_ajax()
{
    // Обработка AJAX запросов для плагинов
    // Реализация будет добавлена позже
    if (function_exists('send_json_response')) {
        send_json_response(['success' => false, 'error' => 'Not implemented'], 501);
    } else {
        header('Content-Type: application/json');
        echo json_encode(['success' => false, 'error' => 'Not implemented']);
        exit;
    }
}
