import {__} from "@wordpress/i18n";
import {validate} from "../../../../../../../../../validations";
import {required, alphanumericAndSpec, isValidEmailFormat} from "../../../../../../../../../validations";

/**
 * Get validator for required field
 *
 * @param {Function} setError Function to set error state
 * @returns {Function} Validator function
 */
export const getRequiredValidator = (setError) => (value) => {
    if (!value || !String(value).trim()) {
        setError(__("This field is required.", 'limb-chatbot'));
        return false;
    }

    setError(false);
    return true;
};

/**
 * Validate slug format (lowercase letters, numbers, and underscores only)
 *
 * @param {string} value Value to validate
 * @returns {Object} Validation result with valid boolean and message
 */
export const validateSlugFormat = (value) => {
    return alphanumericAndSpec(value, '_', {lowercase: true});
};

/**
 * Get validator for unique name field (for parameters)
 * Checks for duplicates only in parameters
 *
 * @param {Function} setError Function to set error state
 * @param {Object} currentItem Current parameter object
 * @param {Array} allParameters All parameters in the action
 * @param {Array} allCallbacks All callbacks in the action
 * @returns {Function} Validator function
 */
export const getParameterNameValidator = (setError, currentItem, allParameters = [], allCallbacks = []) => (value) => {
    // First check required validation
    const res = validate(value, [required]);
    if (!res.valid) {
        setError(res.message);
        return false;
    }

    const trimmedValue = String(value).trim();

    // Check slug format validation
    const slugValidation = validateSlugFormat(trimmedValue);
    if (!slugValidation.valid) {
        setError(slugValidation.message);
        return false;
    }

    // Check for duplicate names in parameters (excluding current parameter)
    const duplicateInParameters = allParameters.some(p =>
        p.id !== currentItem?.id &&
        p.name &&
        p.name.trim().toLowerCase() === trimmedValue.toLowerCase()
    );

    if (duplicateInParameters) {
        setError(__("This name is already taken. Please use a different one.", 'limb-chatbot'));
        return false;
    }

    setError(false);
    return true;
};

/**
 * Get validator for unique name field (for callbacks)
 * Checks for duplicates only in callbacks
 *
 * @param {Function} setError Function to set error state
 * @param {Object} currentItem Current callback object
 * @param {Array} allParameters All parameters in the action
 * @param {Array} allCallbacks All callbacks in the action
 * @returns {Function} Validator function
 */
export const getCallbackNameValidator = (setError, currentItem, allParameters = [], allCallbacks = []) => (value) => {
    // First check required validation
    if (!value || !String(value).trim()) {
        setError(__("This field is required.", 'limb-chatbot'));
        return false;
    }

    const trimmedValue = String(value).trim();

    // Check slug format validation
    const slugValidation = validateSlugFormat(trimmedValue);
    if (!slugValidation.valid) {
        setError(slugValidation.message);
        return false;
    }

    // Check for duplicate names in callbacks only (excluding current callback)
    const duplicateInCallbacks = allCallbacks.some(c =>
        c.id !== currentItem?.id &&
        c.name &&
        c.name.trim().toLowerCase() === trimmedValue.toLowerCase()
    );

    if (duplicateInCallbacks) {
        setError(__("This name is already taken. Please use a different one.", 'limb-chatbot'));
        return false;
    }

    setError(false);
    return true;
};

/**
 * Validate email format
 * Allows email addresses or variables (e.g., {email})
 * Uses shared email validation utility for core email format validation
 *
 * @param {string} value Value to validate
 * @returns {Object} Validation result with valid boolean and message
 */
export const validateEmailFormat = (value) => {
    if (!value || typeof value !== 'string') {
        return {
            valid: false,
            message: __("Please enter a valid email address.", 'limb-chatbot')
        };
    }

    const trimmedValue = value.trim();

    // Allow empty (for optional fields)
    if (trimmedValue === '') {
        return {
            valid: true
        };
    }

    // Check if it's a variable (starts with { and ends with }, and contains only the variable)
    // This ensures it's a pure variable like {email}, not something like "test@{email}"
    if (trimmedValue.startsWith('{') && trimmedValue.endsWith('}') && trimmedValue.indexOf('@') === -1) {
        return {
            valid: true
        };
    }

    // Use shared email validation utility for core email format validation
    if (!isValidEmailFormat(trimmedValue)) {
        return {
            valid: false,
            message: __("Please enter a valid email address.", 'limb-chatbot')
        };
    }

    return {
        valid: true
    };
};

/**
 * Get validator for email field (required)
 *
 * @param {Function} setError Function to set error state
 * @returns {Function} Validator function
 */
export const getEmailValidator = (setError) => (value) => {
    // First check required validation
    const res = validate(value, [required]);
    if (!res.valid) {
        setError(res.message);
        return false;
    }

    // Then check email format
    const emailValidation = validateEmailFormat(value);
    if (!emailValidation.valid) {
        setError(emailValidation.message);
        return false;
    }

    setError(false);
    return true;
};

/**
 * Get validator for optional email field
 *
 * @param {Function} setError Function to set error state
 * @returns {Function} Validator function
 */
export const getOptionalEmailValidator = (setError) => (value) => {
    // If empty, it's valid (optional field)
    if (!value || !String(value).trim()) {
        setError(false);
        return true;
    }

    // Check email format
    const emailValidation = validateEmailFormat(value);
    if (!emailValidation.valid) {
        setError(emailValidation.message);
        return false;
    }

    setError(false);
    return true;
};