<?php

namespace App\Core;

/**
 * Core Validation Engine
 * Handles data validation before processing.
 */
class Validator
{
    private array $errors = [];

    /**
     * Validate an array of data against rules.
     * Example rules: ['email' => 'required|email', 'password' => 'required|min:8']
     */
    public function validate(array $data, array $rules): bool
    {
        $this->errors = [];

        foreach ($rules as $field => $ruleString) {
            $rulesArray = explode('|', $ruleString);
            $value = $data[$field] ?? null;

            foreach ($rulesArray as $rule) {
                $this->applyRule($field, $value, $rule);
            }
        }

        return empty($this->errors);
    }

    /**
     * Get validation errors.
     */
    public function getErrors(): array
    {
        return $this->errors;
    }

    /**
     * Apply a specific rule to a field's value.
     */
    private function applyRule(string $field, $value, string $rule): void
    {
        // Parse rule with parameters (e.g., min:8)
        $params = [];
        if (strpos($rule, ':') !== false) {
            list($rule, $paramStr) = explode(':', $rule, 2);
            $params = explode(',', $paramStr);
        }

        switch ($rule) {
            case 'required':
                if ($value === null || trim((string)$value) === '') {
                    $this->addError($field, "The {$field} field is required.");
                }
                break;

            case 'email':
                if ($value && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
                    $this->addError($field, "The {$field} must be a valid email address.");
                }
                break;

            case 'min':
                $min = (int)($params[0] ?? 0);
                if ($value && strlen((string)$value) < $min) {
                    $this->addError($field, "The {$field} must be at least {$min} characters.");
                }
                break;

            case 'max':
                $max = (int)($params[0] ?? 0);
                if ($value && strlen((string)$value) > $max) {
                    $this->addError($field, "The {$field} must not exceed {$max} characters.");
                }
                break;
                
            case 'numeric':
                if ($value && !is_numeric($value)) {
                    $this->addError($field, "The {$field} must be a number.");
                }
                break;
                
            case 'strong_password':
                // At least 8 chars, 1 uppercase, 1 lowercase, 1 number
                if ($value && !preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/', $value)) {
                    $this->addError($field, "The {$field} must be at least 8 characters long and contain uppercase, lowercase, and a number.");
                }
                break;
        }
    }

    private function addError(string $field, string $message): void
    {
        if (!isset($this->errors[$field])) {
            $this->errors[$field] = [];
        }
        $this->errors[$field][] = $message;
    }
}
