<?php

/**
 * Хелпер для централизованной санитизации входных данных
 * Унифицированные методы для очистки данных
 *
 * @package Flowaxy\Support\Helpers
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Helpers;

use Flowaxy\Infrastructure\Security\Security;

final class SanitizationHelper
{
    /**
     * Санитизация slug
     *
     * @param string $slug Slug для санитизации
     * @return string
     */
    public static function sanitizeSlug(string $slug): string
    {
        // Удаляем все символы, кроме латинских букв, цифр, дефисов и подчеркиваний
        $slug = preg_replace('/[^a-z0-9\-_]/i', '', $slug);

        // Удаляем множественные дефисы и подчеркивания
        $slug = preg_replace('/[-_]+/', '-', $slug);

        // Удаляем дефисы и подчеркивания в начале и конце
        $slug = trim($slug, '-_');

        // Приводим к нижнему регистру
        $slug = strtolower($slug);

        return $slug;
    }

    /**
     * Санитизация строки
     *
     * @param string $string Строка для санитизации
     * @param bool $stripTags Удалять HTML теги
     * @return string
     */
    public static function sanitizeString(string $string, bool $stripTags = true): string
    {
        if ($stripTags) {
            $string = strip_tags($string);
        }

        // Используем Security::clean если доступен
        if (class_exists(Security::class)) {
            return Security::clean($string);
        }

        // Fallback: базовая очистка
        return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
    }

    /**
     * Санитизация массива
     *
     * @param array<string, mixed> $array Массив для санитизации
     * @param bool $recursive Рекурсивная санитизация
     * @return array<string, mixed>
     */
    public static function sanitizeArray(array $array, bool $recursive = true): array
    {
        $sanitized = [];

        foreach ($array as $key => $value) {
            $sanitizedKey = is_string($key) ? self::sanitizeString($key, false) : $key;

            if (is_array($value) && $recursive) {
                $sanitized[$sanitizedKey] = self::sanitizeArray($value, true);
            } elseif (is_string($value)) {
                $sanitized[$sanitizedKey] = self::sanitizeString($value);
            } else {
                $sanitized[$sanitizedKey] = $value;
            }
        }

        return $sanitized;
    }

    /**
     * Санитизация email
     *
     * @param string $email Email для санитизации
     * @return string
     */
    public static function sanitizeEmail(string $email): string
    {
        // Удаляем пробелы
        $email = trim($email);

        // Приводим к нижнему регистру
        $email = strtolower($email);

        // Фильтруем email
        $email = filter_var($email, FILTER_SANITIZE_EMAIL);

        return $email;
    }

    /**
     * Санитизация URL
     *
     * @param string $url URL для санитизации
     * @return string
     */
    public static function sanitizeUrl(string $url): string
    {
        // Фильтруем URL
        $url = filter_var($url, FILTER_SANITIZE_URL);

        return $url;
    }

    /**
     * Санитизация целого числа
     *
     * @param mixed $value Значение для санитизации
     * @param int|null $min Минимальное значение
     * @param int|null $max Максимальное значение
     * @return int
     */
    public static function sanitizeInt($value, ?int $min = null, ?int $max = null): int
    {
        $intValue = (int)$value;

        if ($min !== null && $intValue < $min) {
            return $min;
        }

        if ($max !== null && $intValue > $max) {
            return $max;
        }

        return $intValue;
    }

    /**
     * Санитизация числа с плавающей точкой
     *
     * @param mixed $value Значение для санитизации
     * @param float|null $min Минимальное значение
     * @param float|null $max Максимальное значение
     * @return float
     */
    public static function sanitizeFloat($value, ?float $min = null, ?float $max = null): float
    {
        $floatValue = (float)filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

        if ($min !== null && $floatValue < $min) {
            return $min;
        }

        if ($max !== null && $floatValue > $max) {
            return $max;
        }

        return $floatValue;
    }

    /**
     * Санитизация через SecurityHelper::sanitizeInput
     *
     * @param mixed $input Входные данные
     * @return string
     */
    public static function sanitizeInput($input): string
    {
        return SecurityHelper::sanitizeInput($input);
    }

    /**
     * Санитизация имени файла
     *
     * @param string $filename Имя файла
     * @return string
     */
    public static function sanitizeFilename(string $filename): string
    {
        // Удаляем путь
        $filename = basename($filename);

        // Удаляем опасные символы
        $filename = preg_replace('/[^a-z0-9\-_.]/i', '', $filename);

        // Удаляем множественные точки
        $filename = preg_replace('/\.{2,}/', '.', $filename);

        return $filename;
    }
}
