<?php

/**
 * Фасад для роботи з валідацією
 *
 * @package Flowaxy\Support\Facades
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Facades;

use Flowaxy\Support\Validation\Validator as ValidatorInstance;
use Flowaxy\Support\Helpers\ValidationHelper;

use function class_exists;

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

    /**
     * Створити валідатор
     *
     * @param array<string, mixed> $data
     * @param array<string, array<int, string>> $rules
     * @return array{valid: bool, errors: array<string, array<int, string>>}
     */
    public static function make(array $data, array $rules): array
    {
        return match (true) {
            class_exists(ValidationHelper::class) => ValidationHelper::validate($data, $rules),
            default => ['valid' => false, 'errors' => []],
        };
    }

    /**
     * Валідувати дані
     *
     * @param array<string, mixed> $data
     * @param array<string, array<int, string>> $rules
     * @return bool
     */
    public static function validate(array $data, array $rules): bool
    {
        $result = self::make($data, $rules);

        return $result['valid'];
    }

    /**
     * Перевірити, чи валідація не пройшла
     *
     * @param array<string, mixed> $data
     * @param array<string, array<int, string>> $rules
     * @return bool
     */
    public static function fails(array $data, array $rules): bool
    {
        return !self::validate($data, $rules);
    }

    /**
     * Перевірити, чи валідація пройшла
     *
     * @param array<string, mixed> $data
     * @param array<string, array<int, string>> $rules
     * @return bool
     */
    public static function passes(array $data, array $rules): bool
    {
        return self::validate($data, $rules);
    }

    /**
     * Отримати помилки валідації
     *
     * @param array<string, mixed> $data
     * @param array<string, array<int, string>> $rules
     * @return array<string, array<int, string>>
     */
    public static function errors(array $data, array $rules): array
    {
        $result = self::make($data, $rules);

        return $result['errors'];
    }

    /**
     * Отримати першу помилку для поля
     *
     * @param array<string, mixed> $data
     * @param array<string, array<int, string>> $rules
     * @param string $field
     * @return string|null
     */
    public static function get(array $data, array $rules, string $field): ?string
    {
        $errors = self::errors($data, $rules);

        return $errors[$field][0] ?? null;
    }

    /**
     * Отримати правила валідації
     *
     * @return array<string, array<int, string>>
     */
    public static function rules(): array
    {
        return [];
    }

    /**
     * Отримати повідомлення валідації
     *
     * @return array<string, string>
     */
    public static function messages(): array
    {
        return [];
    }
}
