<?php

declare(strict_types=1);

require_once __DIR__ . '/helpers.php';

function validate_required(array $data, array $fields, array &$errors): void
{
    foreach ($fields as $field => $label) {
        $value = trim((string) ($data[$field] ?? ''));

        if ($value === '') {
            $errors[$field] = $label . ' is required.';
        }
    }
}

function validate_email_field(array $data, string $field, string $label, array &$errors): void
{
    $value = trim((string) ($data[$field] ?? ''));

    if ($value === '') {
        return;
    }

    if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
        $errors[$field] = $label . ' must be a valid email address.';
    }
}

function validate_phone_field(array $data, string $field, string $label, array &$errors): void
{
    $value = trim((string) ($data[$field] ?? ''));

    if ($value === '') {
        return;
    }

    if (!preg_match('/^[0-9+\-()\s]{7,20}$/', $value)) {
        $errors[$field] = $label . ' format is invalid.';
    }
}

function validate_in_array_field(array $data, string $field, array $allowed, string $label, array &$errors): void
{
    $value = (string) ($data[$field] ?? '');

    if ($value === '') {
        return;
    }

    if (!in_array($value, $allowed, true)) {
        $errors[$field] = $label . ' selection is invalid.';
    }
}

function validate_date_field(array $data, string $field, string $label, array &$errors): void
{
    $value = trim((string) ($data[$field] ?? ''));

    if ($value === '') {
        return;
    }

    $date = \DateTime::createFromFormat('Y-m-d', $value);
    $isValid = $date instanceof \DateTime && $date->format('Y-m-d') === $value;

    if (!$isValid) {
        $errors[$field] = $label . ' must be a valid date.';
    }
}

function validate_numeric_min(array $data, string $field, string $label, int|float $min, array &$errors): void
{
    $value = trim((string) ($data[$field] ?? ''));

    if ($value === '') {
        return;
    }

    if (!is_numeric($value) || (float) $value < $min) {
        $errors[$field] = sprintf('%s must be at least %s.', $label, (string) $min);
    }
}

function validate_date_order(string $startDate, string $endDate, string $startLabel, string $endLabel, array &$errors, string $field = 'end_date'): void
{
    if ($startDate === '' || $endDate === '') {
        return;
    }

    if (strtotime($endDate) < strtotime($startDate)) {
        $errors[$field] = $endLabel . ' must be on or after ' . strtolower($startLabel) . '.';
    }
}

function validate_password_confirmation(array $data, string $passwordField, string $confirmationField, array &$errors): void
{
    $password = (string) ($data[$passwordField] ?? '');
    $confirmation = (string) ($data[$confirmationField] ?? '');

    if ($password === '') {
        return;
    }

    if (strlen($password) < 8) {
        $errors[$passwordField] = 'Password must be at least 8 characters.';
    }

    if ($password !== $confirmation) {
        $errors[$confirmationField] = 'Password confirmation does not match.';
    }
}

function duplicate_exists(
    string $table,
    string $column,
    string $value,
    ?int $ignoreId = null,
    string $idColumn = 'id'
): bool {
    $sql = sprintf('SELECT COUNT(*) FROM %s WHERE %s = :value', $table, $column);
    $params = ['value' => $value];

    if ($ignoreId !== null) {
        $sql .= sprintf(' AND %s <> :ignore_id', $idColumn);
        $params['ignore_id'] = $ignoreId;
    }

    return (int) db_fetch_value($sql, $params, 0) > 0;
}

function validation_error(array $errors, string $field): ?string
{
    return $errors[$field] ?? null;
}
