<?php

namespace SGC\eGiftCard\Http\Request;

defined( 'ABSPATH' ) || exit; // Prevent direct file access.
/**
 * Class Validator
 *
 * Validates data based on specified rules and error messages.
 */
class Validator {
    /**
     * @var array Data to validate.
     */
    private $data = [];

    /**
     * @var array Validation rules.
     */
    private $rules = [];

    /**
     * @var array Custom error messages.
     */
    private $messages = [];

    /**
     * @var array List of validation errors.
     */
    private $errors = [];

    /**
     * Validator constructor.
     *
     * @param array $data The data to validate.
     * @param array $rules The validation rules.
     * @param array $messages Custom error messages.
     */
    public function __construct( array $data, array $rules, array $messages ) {
        $this->data     = $data;
        $this->messages = $messages;

        $this->formatValidatorData( $rules );
    }

    /**
     * Validate the data.
     *
     * @return array List of validation errors.
     */
    public function validate() {
        foreach ( $this->rules as $field => $ruleStr ) {
            $rulesArr = explode( '|', $ruleStr );

            foreach ( $rulesArr as $rule ) {
                if ( method_exists( $this, $rule ) ) {
                    $this->{$rule}( $field );
                }
            }
        }

        return $this->errors;
    }

    /**
     * Check if a field is required.
     *
     * @param string $field The field name.
     * @return void
     */
    private function required( string $field ) {
        if ( ! isset( $this->data[ $field ] ) || empty( $this->data[ $field ] ) ) {
            $this->errors[ $field ] = $this->getMessage( "$field.required", "$field is required." );
        }
    }

    /**
     * Check if a field is a valid email.
     *
     * @param string $field The field name.
     * @return void
     */
    private function email( string $field ) {
        if ( ! is_email( $this->data[ $field ] ) ) {
            $this->errors[ $field ] = $this->getMessage( "$field.email", "$field is not a valid email address." );
        }
    }

    /**
     * Check if a field is a valid array.
     *
     * @param string $field The field name.
     * @return void
     */
    private function array( string $field ) {
        if ( ! is_array( $this->data[ $field ] ) ) {
            $this->errors[ $field ] = $this->getMessage( "$field.array", "$field should be an array." );
        }
    }

    /**
     * Format validation data.
     *
     * @param array $rules The validation rules.
     * @return void
     */
    private function formatValidatorData( array $rules ) {
        foreach ( $rules as $field => $ruleStr ) {
            $this->rules[ $field ] = $ruleStr;
        }
    }

    /**
     * Get a custom error message or return a default message.
     *
     * @param string $messageKey The message key.
     * @param string $default The default message.
     *
     * @return string The error message.
     */
    private function getMessage( string $messageKey, string $default ) {
        return isset( $this->messages[ $messageKey ] ) ? $this->messages[ $messageKey ] : $default;
    }
}