/**
 * RSL Form Validation System
 *
 * Client-side form validation with support for required fields, email validation,
 * URL validation, number validation with min/max constraints, and checkbox/radio
 * group validation. Provides real-time error feedback and accessibility support.
 *
 * @fileoverview Client-side form validation with multiple input type support
 * @version 1.0.0
 * @license MIT
 *
 * Key Features:
 * - Required field validation for all input types
 * - Email format validation with regex pattern
 * - URL validation using native URL constructor
 * - Number validation with min/max range checking
 * - Checkbox and radio button group validation
 * - Real-time error clearing on user input
 * - Visual error indicators with CSS classes
 * - Auto-generated error messages with auto-dismiss
 * - Focus management (automatically focuses first error field)
 * - Dual validation triggers: .input-required class or data-required attribute
 *
 * Usage:
 * // Required text input:
 * <input type="text" class="input-required" placeholder="Name">
 * // or
 * <input type="email" data-required="true" placeholder="Email">
 *
 * // Required email with validation:
 * <input type="email" class="input-required" placeholder="Email">
 *
 * // Number with min/max:
 * <input type="number" class="input-required" min="1" max="100">
 *
 * // Required checkbox group:
 * <input type="checkbox" name="interests" class="input-required" value="1"> Option 1
 * <input type="checkbox" name="interests" class="input-required" value="2"> Option 2
 *
 * // Error message container (auto-generated if not present):
 * <div class="validation-error-message">Please fill in all required fields.</div>
 *
 * Public API:
 * Validation runs automatically on form submit. No manual JavaScript API required.
 * Apply .input-required class or data-required="true" to enable validation.
 * Error styling via .input-error class (applied automatically).
 */

(function() {
    'use strict';

    // Initialize RSL namespace
    window.RSL = window.RSL || {};

    // Track initialized forms to prevent double-initialization
    const initializedForms = new WeakSet();

    /**
     * RSL Form Validation Component
     * Public API for form validation management
     */
    window.RSL.FormValidation = window.RSL.FormValidation || {
        /**
         * Initialize validation for all forms on the page
         * Safe to call multiple times - prevents double-initialization
         */
        init: function() {
            const forms = document.querySelectorAll('form');
            forms.forEach(form => {
                if (!initializedForms.has(form)) {
                    setupFormValidation(form);
                    initializedForms.add(form);
                }
            });
        }
    };

    /**
     * Initialize form validation on DOM ready
     */
    document.addEventListener('DOMContentLoaded', function() {
        window.RSL.FormValidation.init();
    });

    /**
     * Set up validation for a single form
     *
     * Attaches submit event listener for validation and input event listeners
     * for real-time error clearing as users correct their mistakes.
     *
     * @param {HTMLFormElement} form - Form element to validate
     *
     * @example
     * const form = document.querySelector('form');
     * setupFormValidation(form);
     */
    function setupFormValidation(form) {
        // Validate on form submit
        form.addEventListener('submit', (event) => {
            handleFormSubmit(event, form);
        });

        // Set up real-time error clearing
        setupErrorClearing(form);
    }

    /**
     * Handle form submission and validation
     *
     * Validates all required inputs, applies error classes, shows error messages,
     * and prevents submission if validation fails. Focuses the first error field.
     *
     * @param {Event} event - Submit event
     * @param {HTMLFormElement} form - Form being submitted
     *
     * @example
     * form.addEventListener('submit', (event) => {
     *   handleFormSubmit(event, form);
     * });
     */
    function handleFormSubmit(event, form) {
        const inputs = form.querySelectorAll('.input-required, [data-required="true"]');
        let hasErrors = false;

        inputs.forEach(input => {
            const validation = validateInput(input, form);

            if (!validation.isValid) {
                input.classList.add('input-error');
                hasErrors = true;

                // Focus first error field
                if (!form.querySelector('.input-error:focus')) {
                    input.focus();
                }
            } else {
                input.classList.remove('input-error');
            }
        });

        if (hasErrors) {
            event.preventDefault();
            showErrorMessage(form);
        }
    }

    /**
     * Validate a single input element
     *
     * Checks for empty values and performs type-specific validation:
     * - Text/textarea/select: checks for non-empty trimmed value
     * - Email: validates format with regex pattern
     * - URL: validates using URL constructor
     * - Number: checks for valid number and min/max constraints
     * - Checkbox/radio: checks if any in group is checked
     *
     * @param {HTMLInputElement|HTMLTextAreaElement|HTMLSelectElement} input - Input to validate
     * @param {HTMLFormElement} form - Parent form element
     * @returns {{isValid: boolean, isEmpty: boolean, isInvalid: boolean}} Validation result
     *
     * @example
     * const result = validateInput(emailInput, form);
     * if (!result.isValid) {
     *   console.log('Validation failed');
     * }
     */
    function validateInput(input, form) {
        let isEmpty = false;
        let isInvalid = false;

        // Handle checkbox and radio button validation
        if (input.type === 'checkbox' || input.type === 'radio') {
            const name = input.getAttribute('name');
            if (name) {
                // Check if any in the group are checked
                const group = form.querySelectorAll(`[name="${name}"]`);
                const anyChecked = Array.from(group).some(inp => inp.checked);
                isEmpty = !anyChecked;
            } else {
                // Single checkbox/radio without name
                isEmpty = !input.checked;
            }
        } else {
            // Text inputs, textareas, selects
            const value = input.value.trim();
            isEmpty = !value;

            if (!isEmpty) {
                // Type-specific validation
                if (input.type === 'email') {
                    isInvalid = !validateEmail(value);
                } else if (input.type === 'url') {
                    isInvalid = !validateURL(value);
                } else if (input.type === 'number') {
                    isInvalid = !validateNumber(input, value);
                }
            }
        }

        return {
            isValid: !isEmpty && !isInvalid,
            isEmpty,
            isInvalid
        };
    }

    /**
     * Validate email address format
     *
     * Uses a standard email regex pattern to check for valid email structure.
     * Pattern requires: text@text.text format with no whitespace.
     *
     * @param {string} email - Email address to validate
     * @returns {boolean} True if email format is valid
     *
     * @example
     * validateEmail('user@example.com') // returns true
     * validateEmail('invalid-email') // returns false
     */
    function validateEmail(email) {
        const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailPattern.test(email);
    }

    /**
     * Validate URL format
     *
     * Uses the native URL constructor to check for valid URL structure.
     * Catches exception if URL is malformed.
     *
     * @param {string} url - URL to validate
     * @returns {boolean} True if URL is valid
     *
     * @example
     * validateURL('https://example.com') // returns true
     * validateURL('not-a-url') // returns false
     */
    function validateURL(url) {
        try {
            new URL(url);
            return true;
        } catch (e) {
            return false;
        }
    }

    /**
     * Validate number input with min/max constraints
     *
     * Checks if value is a valid number and optionally validates against
     * min and max attributes if present on the input element.
     *
     * @param {HTMLInputElement} input - Number input element
     * @param {string} value - Value to validate
     * @returns {boolean} True if number is valid and within constraints
     *
     * @example
     * // <input type="number" min="1" max="100" value="50">
     * validateNumber(input, '50') // returns true
     * validateNumber(input, '150') // returns false (exceeds max)
     */
    function validateNumber(input, value) {
        const num = parseFloat(value);

        // Check if valid number
        if (isNaN(num)) {
            return false;
        }

        // Check min constraint
        const min = input.getAttribute('min');
        if (min !== null && num < parseFloat(min)) {
            return false;
        }

        // Check max constraint
        const max = input.getAttribute('max');
        if (max !== null && num > parseFloat(max)) {
            return false;
        }

        return true;
    }

    /**
     * Show error message at top of form
     *
     * Creates or displays an error message element at the beginning of the form.
     * Auto-dismisses after 5 seconds. Applies inline styles for visibility.
     *
     * @param {HTMLFormElement} form - Form to show error message in
     *
     * @example
     * showErrorMessage(form);
     * // Displays: "Please fill in all required fields."
     */
    function showErrorMessage(form) {
        let errorMsg = form.querySelector('.validation-error-message');

        if (!errorMsg) {
            errorMsg = document.createElement('div');
            errorMsg.className = 'validation-error-message';
            errorMsg.style.cssText = 'color: #dc3545; padding: 1rem; margin: 1rem 0; background: rgba(220, 53, 69, 0.1); border-radius: 4px; font-weight: 600;';
            errorMsg.textContent = 'Please fill in all required fields.';
            form.insertBefore(errorMsg, form.firstChild);
        }

        // Auto-remove after 5 seconds
        setTimeout(() => {
            if (errorMsg && errorMsg.parentNode) {
                errorMsg.remove();
            }
        }, 5000);
    }

    /**
     * Set up real-time error clearing on input
     *
     * Adds event listeners to all required inputs to remove error styling
     * as users type or change values. For checkbox/radio groups, clears
     * errors on all inputs in the group.
     *
     * @param {HTMLFormElement} form - Form containing inputs
     *
     * @example
     * setupErrorClearing(form);
     * // Now all required inputs will clear errors on change
     */
    function setupErrorClearing(form) {
        const allInputs = form.querySelectorAll('.input-required, [data-required="true"]');

        allInputs.forEach(input => {
            // Text inputs, textareas, selects
            input.addEventListener('input', () => {
                if (input.value.trim()) {
                    input.classList.remove('input-error');
                }
            });

            // Checkboxes and radios
            if (input.type === 'checkbox' || input.type === 'radio') {
                input.addEventListener('change', () => {
                    const name = input.getAttribute('name');
                    if (name) {
                        // Clear error for all inputs in the group
                        const group = form.querySelectorAll(`[name="${name}"]`);
                        group.forEach(inp => {
                            inp.classList.remove('input-error');
                        });
                    } else {
                        input.classList.remove('input-error');
                    }
                });
            }
        });
    }

    /**
     * Public API: Validate a single field programmatically
     *
     * Allows external components (like custom select, date pickers, etc.)
     * to trigger validation on their hidden form fields. This integrates
     * custom components with the RSL form validation system.
     *
     * @param {HTMLElement} field - Input, select, or textarea element to validate
     * @returns {boolean} True if field is valid, false otherwise
     *
     * @example
     * // From custom component
     * if (window.RSL && window.RSL.FormValidation) {
     *     window.RSL.FormValidation.validateField(hiddenSelectElement);
     * }
     */
    window.RSL.FormValidation.validateField = function(field) {
        if (!field) {
            return true;
        }

        // Only validate if field is required
        const isRequired = field.classList.contains('input-required') ||
                          field.getAttribute('data-required') === 'true';

        if (!isRequired) {
            return true;
        }

        // Validate the field
        const validation = validateInput(field);

        // Apply or remove error styling based on validation result
        if (!validation.isValid) {
            field.classList.add('input-error');
            return false;
        } else {
            field.classList.remove('input-error');
            return true;
        }
    };

})();
