<?php

declare(strict_types=1);

namespace Flowaxy\Support\Services;

use Flowaxy\Core\System\PathResolver;
use Flowaxy\Support\Helpers\ClassLoaderHelper;
use Flowaxy\Support\Helpers\FileHelper;
use Flowaxy\Support\Validation\Validator;
use Flowaxy\Support\Facades\Log;
use Exception;
use Throwable;

use function preg_match;
use function strlen;
use const DS;

// Сервис для централизованной валидации
// Унифицированные методы валидации для разных типов данных
class ValidationService
{
    // Получение экземпляра Validator
    private function getValidator(): Validator
    {
        ClassLoaderHelper::ensureLoaded(Validator::class);
        return new Validator();
    }

    // Валидация slug
    public function validateSlug(string $slug): array
    {
        if (empty($slug)) {
            return [
                'valid' => false,
                'error' => 'Slug не може бути порожнім',
            ];
        }

        if (!preg_match('/^[a-z0-9\-_]+$/i', $slug)) {
            return [
                'valid' => false,
                'error' => 'Slug може містити тільки латинські літери, цифри, дефіси та підкреслення',
            ];
        }

        if (strlen($slug) > 100) {
            return [
                'valid' => false,
                'error' => 'Slug не може бути довшим за 100 символів',
            ];
        }

        return ['valid' => true];
    }

    // Валидация файла
    public function validateFile(array $file, array $options = []): array
    {
        // Проверка наличия файла
        if (empty($file) || !isset($file['tmp_name'])) {
            return [
                'valid' => false,
                'error' => 'Файл не вибрано',
            ];
        }

        // Проверка ошибок загрузки
        if (!isset($file['error']) || $file['error'] !== UPLOAD_ERR_OK) {
            $errorMessages = [
                UPLOAD_ERR_INI_SIZE => 'Файл перевищує максимальний розмір, встановлений в php.ini',
                UPLOAD_ERR_FORM_SIZE => 'Файл перевищує максимальний розмір, встановлений у формі',
                UPLOAD_ERR_PARTIAL => 'Файл був завантажений лише частково',
                UPLOAD_ERR_NO_FILE => 'Файл не був завантажений',
                UPLOAD_ERR_NO_TMP_DIR => 'Відсутня тимчасова директорія',
                UPLOAD_ERR_CANT_WRITE => 'Не вдалося записати файл на диск',
                UPLOAD_ERR_EXTENSION => 'Розширення PHP зупинило завантаження файлу',
            ];

            $error = $file['error'] ?? UPLOAD_ERR_NO_FILE;
            return [
                'valid' => false,
                'error' => $errorMessages[$error] ?? 'Невідома помилка завантаження',
            ];
        }

        // Проверка размера
        if (isset($options['max_size'])) {
            $fileSize = $file['size'] ?? 0;
            if ($fileSize > $options['max_size']) {
                return [
                    'valid' => false,
                    'error' => 'Файл перевищує максимальний розмір',
                ];
            }
        }

        // Проверка расширения
        if (isset($options['allowed_extensions']) && !empty($options['allowed_extensions'])) {
            $extension = strtolower(pathinfo($file['name'] ?? '', PATHINFO_EXTENSION));
            if (!in_array($extension, array_map('strtolower', $options['allowed_extensions']), true)) {
                return [
                    'valid' => false,
                    'error' => 'Недозволене розширення файлу',
                ];
            }
        }

        // Проверка MIME типа
        if (isset($options['allowed_mime_types']) && !empty($options['allowed_mime_types'])) {
            $mimeType = $file['type'] ?? '';
            if (!in_array($mimeType, $options['allowed_mime_types'], true)) {
                return [
                    'valid' => false,
                    'error' => 'Недозволений MIME тип файлу',
                ];
            }
        }

        return ['valid' => true];
    }

    // Валидация темы
    public function validateTheme(string $themeSlug): array
    {
        $slugValidation = $this->validateSlug($themeSlug);
        if (!$slugValidation['valid']) {
            return $slugValidation;
        }

        // Дополнительные проверки для темы
        $themePath = PathResolver::theme($themeSlug);
        if (!FileHelper::isDirectory($themePath)) {
            return [
                'valid' => false,
                'error' => 'Тема не знайдена',
            ];
        }

        $themePhpPath = $themePath . DS . 'Theme.php';
        if (!FileHelper::exists($themePhpPath)) {
            return [
                'valid' => false,
                'error' => 'Тема не містить Theme.php',
            ];
        }

        // Проверяем, что ThemeMetadataHelper может прочитать метаданные
        if (class_exists(\Flowaxy\Support\Helpers\ThemeMetadataHelper::class)) {
            $slug = basename($themePath);
            $metadata = \Flowaxy\Support\Helpers\ThemeMetadataHelper::readMetadata($slug);
            if (empty($metadata) || empty($metadata['slug'])) {
                return [
                    'valid' => false,
                    'error' => 'Тема не містить валідні метадані в Theme.php',
                ];
            }
        }

        return ['valid' => true];
    }

    // Валидация плагина
    public function validatePlugin(string $pluginSlug): array
    {
        $slugValidation = $this->validateSlug($pluginSlug);
        if (!$slugValidation['valid']) {
            return $slugValidation;
        }

        // Дополнительные проверки для плагина
        $pluginPath = PathResolver::plugin($pluginSlug);
        if (!FileHelper::isDirectory($pluginPath)) {
            return [
                'valid' => false,
                'error' => 'Плагін не знайдено',
            ];
        }

        $pluginJsonPath = $pluginPath . DS . 'plugin.json';
        if (!FileHelper::exists($pluginJsonPath)) {
            return [
                'valid' => false,
                'error' => 'Плагін не містить plugin.json',
            ];
        }

        return ['valid' => true];
    }

    // Валидация строки
    public function validateString(string $value, array $options = []): array
    {
        $minLength = $options['min_length'] ?? 0;
        $maxLength = $options['max_length'] ?? null;
        $required = $options['required'] ?? false;

        if ($required && empty(trim($value))) {
            return [
                'valid' => false,
                'error' => 'Поле обов\'язкове для заповнення',
            ];
        }

        if (strlen($value) < $minLength) {
            return [
                'valid' => false,
                'error' => "Мінімальна довжина: {$minLength} символів",
            ];
        }

        if ($maxLength !== null && strlen($value) > $maxLength) {
            return [
                'valid' => false,
                'error' => "Максимальна довжина: {$maxLength} символів",
            ];
        }

        return ['valid' => true];
    }

    // Валидация email
    public function validateEmail(string $email): array
    {
        if (empty($email)) {
            return [
                'valid' => false,
                'error' => 'Email не може бути порожнім',
            ];
        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return [
                'valid' => false,
                'error' => 'Невірний формат email',
            ];
        }

        return ['valid' => true];
    }
}
