<?php
// app/Helpers/validation.php - Validation Functions

// Validate required field
function is_required($value) {
    return !empty(trim($value));
}

// Validate minimum length
function min_length($value, $min) {
    return strlen(trim($value)) >= $min;
}

// Validate maximum length
function max_length($value, $max) {
    return strlen(trim($value)) <= $max;
}

// Validate exact length
function exact_length($value, $length) {
    return strlen(trim($value)) === $length;
}

// Validate email
function is_valid_email($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

// Validate phone number (Nigerian format)
function is_valid_phone($phone) {
    $phone = preg_replace('/[\s\-]/', '', $phone);
    $pattern = '/^(\+?234|0)?[789][01]\d{8}$/';
    return preg_match($pattern, $phone) === 1;
}

// Validate URL
function is_valid_url($url) {
    return filter_var($url, FILTER_VALIDATE_URL) !== false;
}

// Validate amount/number
function is_valid_amount($amount) {
    return is_numeric($amount) && $amount > 0;
}

// Validate integer
function is_valid_integer($value) {
    return filter_var($value, FILTER_VALIDATE_INT) !== false;
}

// Validate float
function is_valid_float($value) {
    return filter_var($value, FILTER_VALIDATE_FLOAT) !== false;
}

// Validate date
function is_valid_date($date, $format = 'Y-m-d') {
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) === $date;
}

// Validate date range
function is_valid_date_range($start_date, $end_date) {
    return strtotime($start_date) <= strtotime($end_date);
}

// Validate password strength
function is_strong_password($password, $min_length = 8) {
    if (strlen($password) < $min_length) {
        return false;
    }
    
    // Check for at least one uppercase, one lowercase, one number
    if (!preg_match('/[A-Z]/', $password)) {
        return false;
    }
    if (!preg_match('/[a-z]/', $password)) {
        return false;
    }
    if (!preg_match('/[0-9]/', $password)) {
        return false;
    }
    
    return true;
}

// Validate passwords match
function passwords_match($password, $confirm_password) {
    return $password === $confirm_password;
}

// Validate unique email in database
function is_unique_email($email, $exclude_id = null) {
    $db = Database::getInstance();
    
    if ($exclude_id) {
        $sql = "SELECT id FROM users WHERE email = ? AND id != ? LIMIT 1";
        $result = $db->fetch($sql, [$email, $exclude_id]);
    } else {
        $sql = "SELECT id FROM users WHERE email = ? LIMIT 1";
        $result = $db->fetch($sql, [$email]);
    }
    
    return $result === null;
}

// Validate file upload
function is_valid_file_upload($file, $allowed_extensions = [], $max_size = null) {
    if (!isset($file['error']) || is_array($file['error'])) {
        return false;
    }
    
    if ($file['error'] !== UPLOAD_ERR_OK) {
        return false;
    }
    
    // Check file size
    $max_size = $max_size ?: MAX_FILE_SIZE;
    if ($file['size'] > $max_size) {
        return false;
    }
    
    // Check extension
    if (!empty($allowed_extensions)) {
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, $allowed_extensions)) {
            return false;
        }
    }
    
    return true;
}

// Validate image file
function is_valid_image($file) {
    $allowed = explode(',', ALLOWED_IMAGE_TYPES);
    return is_valid_file_upload($file, $allowed);
}

// Validate document file
function is_valid_document($file) {
    $allowed = explode(',', ALLOWED_DOCUMENT_TYPES);
    return is_valid_file_upload($file, $allowed);
}

// Validate alphanumeric
function is_alphanumeric($value) {
    return preg_match('/^[a-zA-Z0-9]+$/', $value) === 1;
}

// Validate alphabetic only
function is_alphabetic($value) {
    return preg_match('/^[a-zA-Z\s]+$/', $value) === 1;
}

// Validate numeric only
function is_numeric_only($value) {
    return preg_match('/^[0-9]+$/', $value) === 1;
}

// Validate between range
function is_between($value, $min, $max) {
    return $value >= $min && $value <= $max;
}

// Validate matches pattern
function matches_pattern($value, $pattern) {
    return preg_match($pattern, $value) === 1;
}

// Validate in array
function is_in_array($value, $array) {
    return in_array($value, $array);
}

// Comprehensive form validation
function validate($data, $rules) {
    $errors = [];
    
    foreach ($rules as $field => $rule_string) {
        $rules_array = explode('|', $rule_string);
        $value = $data[$field] ?? '';
        
        foreach ($rules_array as $rule) {
            $params = [];
            
            // Check if rule has parameters
            if (strpos($rule, ':') !== false) {
                list($rule, $params_string) = explode(':', $rule, 2);
                $params = explode(',', $params_string);
            }
            
            switch ($rule) {
                case 'required':
                    if (!is_required($value)) {
                        $errors[$field][] = ucfirst(str_replace('_', ' ', $field)) . ' is required';
                    }
                    break;
                    
                case 'email':
                    if (!empty($value) && !is_valid_email($value)) {
                        $errors[$field][] = 'Invalid email format';
                    }
                    break;
                    
                case 'phone':
                    if (!empty($value) && !is_valid_phone($value)) {
                        $errors[$field][] = 'Invalid phone number format';
                    }
                    break;
                    
                case 'min':
                    if (!empty($value) && !min_length($value, $params[0])) {
                        $errors[$field][] = ucfirst(str_replace('_', ' ', $field)) . ' must be at least ' . $params[0] . ' characters';
                    }
                    break;
                    
                case 'max':
                    if (!empty($value) && !max_length($value, $params[0])) {
                        $errors[$field][] = ucfirst(str_replace('_', ' ', $field)) . ' must not exceed ' . $params[0] . ' characters';
                    }
                    break;
                    
                case 'numeric':
                    if (!empty($value) && !is_numeric($value)) {
                        $errors[$field][] = ucfirst(str_replace('_', ' ', $field)) . ' must be numeric';
                    }
                    break;
                    
                case 'integer':
                    if (!empty($value) && !is_valid_integer($value)) {
                        $errors[$field][] = ucfirst(str_replace('_', ' ', $field)) . ' must be an integer';
                    }
                    break;
                    
                case 'amount':
                    if (!empty($value) && !is_valid_amount($value)) {
                        $errors[$field][] = ucfirst(str_replace('_', ' ', $field)) . ' must be a valid amount';
                    }
                    break;
                    
                case 'date':
                    if (!empty($value) && !is_valid_date($value)) {
                        $errors[$field][] = 'Invalid date format';
                    }
                    break;
                    
                case 'url':
                    if (!empty($value) && !is_valid_url($value)) {
                        $errors[$field][] = 'Invalid URL format';
                    }
                    break;
                    
                case 'strong_password':
                    if (!empty($value) && !is_strong_password($value)) {
                        $errors[$field][] = 'Password must be at least 8 characters and contain uppercase, lowercase, and numbers';
                    }
                    break;
                    
                case 'match':
                    if ($value !== ($data[$params[0]] ?? '')) {
                        $errors[$field][] = ucfirst(str_replace('_', ' ', $field)) . ' must match ' . str_replace('_', ' ', $params[0]);
                    }
                    break;
                    
                case 'unique_email':
                    if (!empty($value) && !is_unique_email($value, $params[0] ?? null)) {
                        $errors[$field][] = 'Email already exists';
                    }
                    break;
                    
                case 'in':
                    if (!empty($value) && !is_in_array($value, $params)) {
                        $errors[$field][] = 'Invalid value selected';
                    }
                    break;
                    
                case 'between':
                    if (!empty($value) && !is_between($value, $params[0], $params[1])) {
                        $errors[$field][] = ucfirst(str_replace('_', ' ', $field)) . ' must be between ' . $params[0] . ' and ' . $params[1];
                    }
                    break;
            }
        }
    }
    
    return [
        'valid' => empty($errors),
        'errors' => $errors
    ];
}

// Get first error message for a field
function get_error($field, $errors) {
    if (isset($errors[$field]) && !empty($errors[$field])) {
        return $errors[$field][0];
    }
    return null;
}

// Display all errors
function display_errors($errors) {
    if (empty($errors)) {
        return '';
    }
    
    $html = '<div class="alert alert-danger"><ul class="mb-0">';
    foreach ($errors as $field => $field_errors) {
        foreach ($field_errors as $error) {
            $html .= '<li>' . htmlspecialchars($error) . '</li>';
        }
    }
    $html .= '</ul></div>';
    
    return $html;
}
