<?php

/**
 * Фасад для роботи з безпекою
 *
 * @package Flowaxy\Support\Facades
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Facades;

use Flowaxy\Infrastructure\Security\Security as SecurityInstance;
use Flowaxy\Infrastructure\Security\Hash as HashInstance;
use Flowaxy\Infrastructure\Security\Encryption as EncryptionInstance;
use Flowaxy\Support\Helpers\ValidationHelper;

use function class_exists;
use function is_array;
use function base64_encode;
use function base64_decode;

final class Security extends Facade
{
    protected static function getFacadeAccessor(): string
    {
        return SecurityInstance::class;
    }

    /**
     * Отримати екземпляр Security
     *
     * @return SecurityInstance
     */
    private static function security(): SecurityInstance
    {
        return static::getFacadeRoot();
    }

    /**
     * Генерація CSRF токена
     *
     * @return string
     */
    public static function csrfToken(): string
    {
        return static::security()->csrfToken();
    }

    /**
     * Перевірка CSRF токена
     *
     * @param string|null $token
     * @return bool
     */
    public static function verifyCsrfToken(?string $token = null): bool
    {
        return static::security()->verifyCsrfToken($token);
    }

    /**
     * Генерація CSRF поля для форми
     *
     * @return string
     */
    public static function csrfField(): string
    {
        return static::security()->csrfField();
    }

    /**
     * Хешування значення
     *
     * @param string $value
     * @return string
     */
    public static function hash(string $value): string
    {
        $hashInstance = new HashInstance();
        return $hashInstance->make($value);
    }

    /**
     * Перевірка хешу
     *
     * @param string $value
     * @param string $hash
     * @return bool
     */
    public static function verify(string $value, string $hash): bool
    {
        $hashInstance = new HashInstance();
        return $hashInstance->check($value, $hash);
    }

    /**
     * Шифрування значення
     *
     * @param string $value
     * @return string
     */
    public static function encrypt(string $value): string
    {
        return match (true) {
            class_exists(EncryptionInstance::class) => EncryptionInstance::quickEncrypt($value),
            default => base64_encode($value),
        };
    }

    /**
     * Розшифрування значення
     *
     * @param string $value
     * @return string
     */
    public static function decrypt(string $value): string
    {
        return match (true) {
            class_exists(EncryptionInstance::class) => EncryptionInstance::quickDecrypt($value),
            default => base64_decode($value, true) ?: '',
        };
    }

    /**
     * Санітизація вхідних даних
     *
     * @param mixed $input
     * @return string
     */
    public static function sanitize(mixed $input): string
    {
        return static::security()->clean($input);
    }

    /**
     * Валідація даних
     *
     * @param mixed $data
     * @param array<string, array<int, string>> $rules
     * @return bool
     */
    public static function validate(mixed $data, array $rules): bool
    {
        if (!class_exists(ValidationHelper::class)) {
            return false;
        }

        $result = ValidationHelper::validate(
            is_array($data) ? $data : [$data],
            $rules
        );

        return $result['valid'];
    }

    /**
     * Захист від XSS
     *
     * @param string $value
     * @return string
     */
    public static function xss(string $value): string
    {
        return static::security()->clean($value);
    }

    /**
     * Захист від SQL ін'єкцій
     *
     * @param string $value
     * @return string
     */
    public static function sqlInjection(string $value): string
    {
        return static::security()->clean($value, true);
    }
}
