// Validation utilities

// Sanitize and validate card number
const sanitizeCardNumber = (cardNumber) => {
    if (!cardNumber) return null;
    return cardNumber.toString().replace(/\D/g, '');
};

// Validate card number using Luhn algorithm
const validateCardNumber = (cardNumber) => {
    const sanitized = sanitizeCardNumber(cardNumber);
    if (!sanitized || sanitized.length < 13 || sanitized.length > 19) {
        return false;
    }
    
    // Luhn algorithm
    let sum = 0;
    let isEven = false;
    
    for (let i = sanitized.length - 1; i >= 0; i--) {
        let digit = parseInt(sanitized[i]);
        
        if (isEven) {
            digit *= 2;
            if (digit > 9) {
                digit -= 9;
            }
        }
        
        sum += digit;
        isEven = !isEven;
    }
    
    return sum % 10 === 0;
};

// Validate expiration date
const validateExpirationDate = (month, year) => {
    const currentDate = new Date();
    const currentYear = currentDate.getFullYear();
    const currentMonth = currentDate.getMonth() + 1;
    
    const expMonth = parseInt(month);
    const expYear = parseInt(year);
    
    if (expMonth < 1 || expMonth > 12) {
        return false;
    }
    
    if (expYear < currentYear || (expYear === currentYear && expMonth < currentMonth)) {
        return false;
    }
    
    return true;
};

// Validate CVV
const validateCVV = (cvv, cardNumber = null) => {
    if (!cvv) return false;
    
    const cvvStr = cvv.toString();
    
    // American Express cards have 4-digit CVV, others have 3-digit
    const sanitizedCard = sanitizeCardNumber(cardNumber);
    const isAmex = sanitizedCard && (sanitizedCard.startsWith('34') || sanitizedCard.startsWith('37'));
    
    const expectedLength = isAmex ? 4 : 3;
    
    return cvvStr.length === expectedLength && /^\d+$/.test(cvvStr);
};

// Validate email address
const validateEmail = (email) => {
    if (!email) return false;
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
};

// Validate amount
const validateAmount = (amount) => {
    const numAmount = parseFloat(amount);
    return !isNaN(numAmount) && numAmount > 0 && numAmount <= 999999.99;
};

// Sanitize string input
const sanitizeString = (str, maxLength = 255) => {
    if (!str) return '';
    return str.toString().trim().substring(0, maxLength);
};

// Validate billing address
// CRITICAL: Handle multiple field name formats (line1/streetAddress, state/region)
// Client sends: line1, state, postalCode
// QuickBooks expects: streetAddress, region, postalCode
const validateBillingAddress = (address) => {
    if (!address) return true; // Optional
    
    const errors = [];
    
    // Check street address (multiple field name formats)
    const streetAddress = address.streetAddress || address.line1 || address.address;
    if (streetAddress && streetAddress.length > 100) {
        errors.push('Street address too long (max 100 characters)');
    }
    
    // Check city
    if (address.city && address.city.length > 50) {
        errors.push('City name too long (max 50 characters)');
    }
    
    // Check region/state (multiple field name formats)
    const region = address.region || address.state;
    if (region && region.length > 10) {
        errors.push('State/region code too long (max 10 characters)');
    }
    
    // Check postal code (multiple field name formats)
    const postalCode = address.postalCode || address.zipCode || address.zip;
    if (postalCode && postalCode.length > 20) {
        errors.push('Postal code too long (max 20 characters)');
    }
    
    // Check country
    if (address.country && address.country.length > 5) {
        errors.push('Country code too long (max 5 characters)');
    }
    
    return errors.length === 0 ? true : errors;
};

module.exports = {
    sanitizeCardNumber,
    validateCardNumber,
    validateExpirationDate,
    validateCVV,
    validateEmail,
    validateAmount,
    sanitizeString,
    validateBillingAddress
};
