<?php

namespace GriffinForms\Frontend\Security\FieldValidations;

class InputText extends Format
{
    // Custom validation for individual iterations
    protected function customValidate($value, $iteration_index)
    {
        $validations = $this->field->getProp('validations');
    
        // Min characters validation
        if (!empty($validations['min']) && is_numeric($validations['min'])) {
            $this->validateMinLength($value, $iteration_index);
        }
    
        // Max characters validation
        if (!empty($validations['max']) && is_numeric($validations['max'])) {
            $this->validateMaxLength($value, $iteration_index);
        }
    
        // No numbers validation
        if (isset($validations['allow_numbers']) && !$validations['allow_numbers']) {
            $this->validateNoNumbers($value, $iteration_index);
        }
    
        // No spaces validation
        if (isset($validations['allow_spaces']) && !$validations['allow_spaces']) {
            $this->validateNoSpaces($value, $iteration_index);
        }
    
        // No special characters validation
        if (isset($validations['allow_splchars']) && !$validations['allow_splchars']) {
            $this->validateNoSpecialChars($value, $iteration_index);
        }
    
        // Exclude specific characters validation
        if (!empty($validations['exclude']) && strlen($validations['exclude']) > 0) {
            $this->validateExcludeChars($value, $validations['exclude'], $iteration_index);
        }
    
        // Regex pattern validation
        if (!empty($validations['pattern'])) {
            $this->validatePattern($value, $validations['pattern'], $iteration_index);
        }
    }

    private function validateNoNumbers($value, $iteration_index = null)
    {
        if (preg_match('/\d/', $value)) {
            $this->addError(__('This field cannot contain numbers.', 'griffinforms-form-builder'), $iteration_index);
        }
    }
    
    private function validateNoSpaces($value, $iteration_index = null)
    {
        if (preg_match('/\s/', $value)) {
            $this->addError(__('This field cannot contain spaces.', 'griffinforms-form-builder'), $iteration_index);
        }
    }
    
    private function validateNoSpecialChars($value, $iteration_index = null)
    {
        $allowSpaces = $this->field->getProp('validations')['allow_spaces'] ?? true;
        $pattern = $allowSpaces ? '/[^\p{L}\p{N}\s]/u' : '/[^\p{L}\p{N}]/u';
    
        if (preg_match($pattern, $value)) {
            $this->addError(__('This field cannot contain special characters.', 'griffinforms-form-builder'), $iteration_index);
        }
    }
    
    private function validateExcludeChars($value, $exclude_chars, $iteration_index = null)
    {
        if (!is_string($exclude_chars) || empty($exclude_chars)) {
            return;
        }
    
        $pattern = '/[' . preg_quote($exclude_chars, '/') . ']/u';
    
        if (preg_match($pattern, $value)) {
            /* translators: %s is a string of characters that are not allowed in this text field */
            $this->addError(sprintf(__('This field cannot contain the following characters: %s', 'griffinforms-form-builder'), htmlspecialchars($exclude_chars)), $iteration_index);
        }
    }

    // validation Minimum length
    protected function validateMinLength($value, $iteration_index = null)
    {
        $validations = $this->field->getProp('validations');
        $min_length = $validations['min'] ?? 0;
    
        // Get the 'is_required' property from the field
        $is_required = $this->field->getProp('is_required');
    
        // If the field is not required and the value is empty, skip the min length validation
        if (empty($value) && (empty($is_required) || $is_required === '0' || $is_required === 0)) {
            return; // No validation for min length if the field is not required and empty
        }
    
        // If minimum length is defined, check the value
        if (!empty($min_length) && strlen(trim($value)) < $min_length) {
            /* translators: %d is the minimum number of characters required in this text field */
            $this->addError(sprintf(__('Minimum length is %d characters.', 'griffinforms-form-builder'), $min_length), $iteration_index);
        }
    }

    // validation Maximum length
    protected function validateMaxLength($value, $iteration_index = null)
    {
        $validations = $this->field->getProp('validations');
        $max_length = $validations['max'] ?? PHP_INT_MAX;
    
        if (empty($max_length) || $max_length === PHP_INT_MAX) {
            return; // Skip if no maximum length is defined
        }
    
        if (strlen(trim($value)) > $max_length) {
            /* translators: %d is the maximum number of characters allowed in this text field */
            $this->addError(sprintf(__('Maximum length is %d characters.', 'griffinforms-form-builder'), $max_length), $iteration_index);
        }
    }
}