// Validation utilities for form inputs

export const validateRequired = (value, fieldName) => {
  if (!value || (typeof value === 'string' && value.trim() === '')) {
    return `${fieldName} es requerido`;
  }
  return null;
};

export const validateEmail = (email) => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(email)) {
    return 'Formato de email inválido';
  }
  return null;
};

export const validateMinLength = (value, minLength, fieldName) => {
  if (value && value.length < minLength) {
    return `${fieldName} debe tener al menos ${minLength} caracteres`;
  }
  return null;
};

export const validateMaxLength = (value, maxLength, fieldName) => {
  if (value && value.length > maxLength) {
    return `${fieldName} no puede exceder ${maxLength} caracteres`;
  }
  return null;
};

export const validateFileType = (file, allowedTypes) => {
  if (!allowedTypes.includes(file.type)) {
    return `Tipo de archivo no permitido. Solo se permiten: ${allowedTypes.join(', ')}`;
  }
  return null;
};

export const validateFileSize = (file, maxSizeInMB) => {
  const maxSizeInBytes = maxSizeInMB * 1024 * 1024;
  if (file.size > maxSizeInBytes) {
    return `El archivo es demasiado grande. Tamaño máximo: ${maxSizeInMB}MB`;
  }
  return null;
};

// Project-specific validations according to INAB requirements
export const validateProjectForm = (formData) => {
  const errors = {};

  // Required fields validation
  const requiredFields = [
    { key: 'nombreProyecto', name: 'Nombre del Proyecto' },
    { key: 'nombreFinca', name: 'Nombre de la Finca' },
    { key: 'departamento', name: 'Departamento' },
    { key: 'municipio', name: 'Municipio' },
    { key: 'aldea', name: 'Aldea' },
    { key: 'nombrePropietario', name: 'Nombre del Propietario' },
    { key: 'nombreRegenteForestal', name: 'Nombre del Regente Forestal' }
  ];

  requiredFields.forEach(field => {
    const error = validateRequired(formData[field.key], field.name);
    if (error) {
      errors[field.key] = error;
    }
  });

  // Length validations
  if (formData.nombreProyecto) {
    const lengthError = validateMaxLength(formData.nombreProyecto, 200, 'Nombre del Proyecto');
    if (lengthError) errors.nombreProyecto = lengthError;
  }

  if (formData.nombreFinca) {
    const lengthError = validateMaxLength(formData.nombreFinca, 200, 'Nombre de la Finca');
    if (lengthError) errors.nombreFinca = lengthError;
  }

  if (formData.nombrePropietario) {
    const lengthError = validateMaxLength(formData.nombrePropietario, 200, 'Nombre del Propietario');
    if (lengthError) errors.nombrePropietario = lengthError;
  }

  if (formData.nombreRegenteForestal) {
    const lengthError = validateMaxLength(formData.nombreRegenteForestal, 200, 'Nombre del Regente Forestal');
    if (lengthError) errors.nombreRegenteForestal = lengthError;
  }

  return {
    isValid: Object.keys(errors).length === 0,
    errors
  };
};

export const validateDocumentUpload = (file) => {
  const errors = [];

  // File type validation - only PDF allowed
  const typeError = validateFileType(file, ['application/pdf']);
  if (typeError) errors.push(typeError);

  // File size validation - max 5MB
  const sizeError = validateFileSize(file, 5);
  if (sizeError) errors.push(sizeError);

  return {
    isValid: errors.length === 0,
    errors
  };
};

// Rodal-specific validations
export const validateNumber = (value, fieldName, min = null, max = null) => {
  if (isNaN(value) || value === '' || value === null || value === undefined) {
    return `${fieldName} debe ser un número válido`;
  }
  
  const numValue = parseFloat(value);
  
  if (min !== null && numValue < min) {
    return `${fieldName} debe ser mayor o igual a ${min}`;
  }
  
  if (max !== null && numValue > max) {
    return `${fieldName} debe ser menor o igual a ${max}`;
  }
  
  return null;
};

export const validateRodalForm = (formData) => {
  const errors = {};
  const warnings = [];

  // Required fields validation
  const nameError = validateRequired(formData.nombreRodal, 'Nombre del Rodal');
  if (nameError) {
    errors.nombreRodal = nameError;
  }

  const areaError = validateRequired(formData.areaHa, 'Área en Hectáreas');
  if (areaError) {
    errors.areaHa = areaError;
  }

  // Name length validation
  if (formData.nombreRodal) {
    const lengthError = validateMaxLength(formData.nombreRodal, 100, 'Nombre del Rodal');
    if (lengthError) errors.nombreRodal = lengthError;
  }

  // Area validation
  if (formData.areaHa && !errors.areaHa) {
    const numberError = validateNumber(formData.areaHa, 'Área en Hectáreas', 0.01, 10000);
    if (numberError) {
      errors.areaHa = numberError;
    } else {
      const area = parseFloat(formData.areaHa);
      
      // Forest area warnings according to INAB standards
      if (area < 0.1) {
        warnings.push('Área muy pequeña para inventario forestal (< 0.1 ha)');
      } else if (area > 1000) {
        warnings.push('Área muy grande, considere dividir en múltiples rodales (> 1000 ha)');
      }
      
      // Precision warning
      if (area.toString().includes('.') && area.toString().split('.')[1].length > 4) {
        warnings.push('Se recomienda usar máximo 4 decimales para el área');
      }
    }
  }

  return {
    isValid: Object.keys(errors).length === 0,
    errors,
    warnings
  };
};

export const validateRodalName = (name, existingNames = []) => {
  const errors = [];
  
  // Required validation
  const requiredError = validateRequired(name, 'Nombre del Rodal');
  if (requiredError) {
    errors.push(requiredError);
    return { isValid: false, errors };
  }
  
  // Length validation
  const lengthError = validateMaxLength(name, 100, 'Nombre del Rodal');
  if (lengthError) errors.push(lengthError);
  
  // Uniqueness validation
  if (existingNames.includes(name.trim())) {
    errors.push('Ya existe un rodal con este nombre en el proyecto');
  }
  
  // Format validation - only alphanumeric, spaces, hyphens, underscores
  const formatRegex = /^[a-zA-Z0-9\s\-_áéíóúÁÉÍÓÚñÑ]+$/;
  if (!formatRegex.test(name)) {
    errors.push('El nombre solo puede contener letras, números, espacios, guiones y guiones bajos');
  }
  
  return {
    isValid: errors.length === 0,
    errors
  };
};

// Field data validations for forest inventory
export const validateDAP = (dap) => {
  const errors = [];
  const warnings = [];
  
  // Required validation
  const requiredError = validateRequired(dap, 'DAP (Diámetro a la Altura del Pecho)');
  if (requiredError) {
    errors.push(requiredError);
    return { isValid: false, errors, warnings };
  }
  
  // Number validation
  const numberError = validateNumber(dap, 'DAP', 0.1, 500);
  if (numberError) {
    errors.push(numberError);
    return { isValid: false, errors, warnings };
  }
  
  const dapValue = parseFloat(dap);
  
  // Atypical value warnings according to forest inventory standards
  if (dapValue < 5) {
    warnings.push('DAP muy pequeño para inventario forestal estándar (< 5 cm)');
  } else if (dapValue < 10) {
    warnings.push('DAP pequeño, verifique si corresponde a regeneración natural');
  }
  
  if (dapValue > 200) {
    warnings.push('DAP excepcionalmente grande (> 200 cm). ¿Confirma la medición?');
  } else if (dapValue > 100) {
    warnings.push('DAP muy grande (> 100 cm). Verifique la medición.');
  }
  
  // Precision warning
  if (dapValue.toString().includes('.') && dapValue.toString().split('.')[1].length > 1) {
    warnings.push('Se recomienda medir DAP con precisión de 0.1 cm');
  }
  
  return {
    isValid: true,
    errors,
    warnings
  };
};

export const validateHeight = (height) => {
  const errors = [];
  const warnings = [];
  
  // Required validation
  const requiredError = validateRequired(height, 'Altura');
  if (requiredError) {
    errors.push(requiredError);
    return { isValid: false, errors, warnings };
  }
  
  // Number validation
  const numberError = validateNumber(height, 'Altura', 0.1, 100);
  if (numberError) {
    errors.push(numberError);
    return { isValid: false, errors, warnings };
  }
  
  const heightValue = parseFloat(height);
  
  // Atypical value warnings
  if (heightValue < 1) {
    warnings.push('Altura muy baja para inventario forestal (< 1 m)');
  } else if (heightValue < 2) {
    warnings.push('Altura baja, verifique si corresponde a regeneración');
  }
  
  if (heightValue > 60) {
    warnings.push('Altura excepcionalmente grande (> 60 m). ¿Confirma la medición?');
  } else if (heightValue > 40) {
    warnings.push('Altura muy grande (> 40 m). Verifique la medición.');
  }
  
  // Precision warning
  if (heightValue.toString().includes('.') && heightValue.toString().split('.')[1].length > 1) {
    warnings.push('Se recomienda medir altura con precisión de 0.1 m');
  }
  
  return {
    isValid: true,
    errors,
    warnings
  };
};

export const validatePlotNumber = (plotNumber) => {
  const errors = [];
  
  // Required validation
  const requiredError = validateRequired(plotNumber, 'Número de Parcela');
  if (requiredError) {
    errors.push(requiredError);
    return { isValid: false, errors };
  }
  
  // Number validation (positive integer)
  if (!Number.isInteger(Number(plotNumber)) || Number(plotNumber) < 1) {
    errors.push('Número de parcela debe ser un número entero positivo');
    return { isValid: false, errors };
  }
  
  const plotValue = parseInt(plotNumber);
  
  // Range validation
  if (plotValue > 9999) {
    errors.push('Número de parcela demasiado grande (máximo 9999)');
  }
  
  return {
    isValid: errors.length === 0,
    errors
  };
};

export const validateTreeCondition = (condition) => {
  const validConditions = ['Sano', 'Bifurcado', 'Plagado', 'Muerto en Pie'];
  
  const requiredError = validateRequired(condition, 'Condición del Árbol');
  if (requiredError) {
    return { isValid: false, errors: [requiredError] };
  }
  
  if (!validConditions.includes(condition)) {
    return {
      isValid: false,
      errors: [`Condición inválida. Debe ser una de: ${validConditions.join(', ')}`]
    };
  }
  
  return { isValid: true, errors: [] };
};

export const validateSpeciesSelection = (species) => {
  const errors = [];
  
  if (!species) {
    errors.push('Debe seleccionar una especie');
    return { isValid: false, errors };
  }
  
  if (!species.id || !species.nombre_cientifico) {
    errors.push('Datos de especie incompletos');
    return { isValid: false, errors };
  }
  
  return { isValid: true, errors: [] };
};

export const validateGPSCoordinates = (latitude, longitude) => {
  const errors = [];
  const warnings = [];
  
  // Latitude validation
  if (latitude === null || latitude === undefined || latitude === '') {
    errors.push('Latitud es requerida');
  } else {
    const lat = parseFloat(latitude);
    if (isNaN(lat)) {
      errors.push('Latitud debe ser un número válido');
    } else if (lat < -90 || lat > 90) {
      errors.push('Latitud debe estar entre -90 y 90 grados');
    } else {
      // Guatemala is approximately between 13.7° and 17.8° N
      if (lat < 13 || lat > 18) {
        warnings.push('Coordenadas fuera del territorio de Guatemala');
      }
    }
  }
  
  // Longitude validation
  if (longitude === null || longitude === undefined || longitude === '') {
    errors.push('Longitud es requerida');
  } else {
    const lng = parseFloat(longitude);
    if (isNaN(lng)) {
      errors.push('Longitud debe ser un número válido');
    } else if (lng < -180 || lng > 180) {
      errors.push('Longitud debe estar entre -180 y 180 grados');
    } else {
      // Guatemala is approximately between -92.3° and -88.2° W
      if (lng < -93 || lng > -88) {
        warnings.push('Coordenadas fuera del territorio de Guatemala');
      }
    }
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

export const validateFieldRecord = (recordData) => {
  const errors = {};
  const warnings = {};
  
  // Validate plot number
  const plotValidation = validatePlotNumber(recordData.numeroParcela);
  if (!plotValidation.isValid) {
    errors.numeroParcela = plotValidation.errors;
  }
  
  // Validate species
  const speciesValidation = validateSpeciesSelection(recordData.especie);
  if (!speciesValidation.isValid) {
    errors.especie = speciesValidation.errors;
  }
  
  // Validate DAP
  const dapValidation = validateDAP(recordData.dapCm);
  if (!dapValidation.isValid) {
    errors.dapCm = dapValidation.errors;
  }
  if (dapValidation.warnings.length > 0) {
    warnings.dapCm = dapValidation.warnings;
  }
  
  // Validate height
  const heightValidation = validateHeight(recordData.alturaM);
  if (!heightValidation.isValid) {
    errors.alturaM = heightValidation.errors;
  }
  if (heightValidation.warnings.length > 0) {
    warnings.alturaM = heightValidation.warnings;
  }
  
  // Validate tree condition
  const conditionValidation = validateTreeCondition(recordData.condicionArbol);
  if (!conditionValidation.isValid) {
    errors.condicionArbol = conditionValidation.errors;
  }
  
  // Validate GPS coordinates
  const gpsValidation = validateGPSCoordinates(recordData.latitud, recordData.longitud);
  if (!gpsValidation.isValid) {
    errors.coordenadas = gpsValidation.errors;
  }
  if (gpsValidation.warnings.length > 0) {
    warnings.coordenadas = gpsValidation.warnings;
  }
  
  return {
    isValid: Object.keys(errors).length === 0,
    errors,
    warnings
  };
};

// Tree form validation for TreeForm component
export const validateTreeData = (formData) => {
  const errors = {};
  
  // Validate plot number
  if (!formData.numeroParcela || formData.numeroParcela === '') {
    errors.numeroParcela = 'Número de parcela es requerido';
  } else {
    const plotValidation = validatePlotNumber(formData.numeroParcela);
    if (!plotValidation.isValid) {
      errors.numeroParcela = plotValidation.errors[0];
    }
  }
  
  // Validate species
  if (!formData.especieId || formData.especieId === '') {
    errors.especieId = 'Debe seleccionar una especie';
  }
  
  // Validate DAP
  if (!formData.dapCm || formData.dapCm === '') {
    errors.dapCm = 'DAP es requerido';
  } else {
    const dapValidation = validateDAP(formData.dapCm);
    if (!dapValidation.isValid) {
      errors.dapCm = dapValidation.errors[0];
    }
  }
  
  // Validate height
  if (!formData.alturaM || formData.alturaM === '') {
    errors.alturaM = 'Altura es requerida';
  } else {
    const heightValidation = validateHeight(formData.alturaM);
    if (!heightValidation.isValid) {
      errors.alturaM = heightValidation.errors[0];
    }
  }
  
  // Validate tree condition
  const conditionValidation = validateTreeCondition(formData.condicionArbol);
  if (!conditionValidation.isValid) {
    errors.condicionArbol = conditionValidation.errors[0];
  }
  
  return errors;
};

// Real-time validation for individual fields
export const validateFieldRealTime = (fieldName, value, additionalData = {}) => {
  switch (fieldName) {
    case 'numeroParcela':
      return validatePlotNumber(value);
    case 'dapCm':
      return validateDAP(value);
    case 'alturaM':
      return validateHeight(value);
    case 'condicionArbol':
      return validateTreeCondition(value);
    case 'especie':
      return validateSpeciesSelection(value);
    case 'coordenadas':
      return validateGPSCoordinates(additionalData.latitud, additionalData.longitud);
    case 'nombreProyecto':
      return validateProjectName(value);
    case 'nombreFinca':
      return validateFincaName(value);
    case 'nombrePropietario':
      return validateOwnerName(value);
    case 'nombreRegenteForestal':
      return validateRegentName(value);
    case 'departamento':
      return validateDepartment(value);
    case 'municipio':
      return validateMunicipality(value);
    case 'aldea':
      return validateVillage(value);
    case 'nombreRodal':
      return validateRodalNameRealTime(value, additionalData.existingNames);
    case 'areaHa':
      return validateAreaRealTime(value);
    case 'email':
      return validateEmailRealTime(value);
    case 'password':
      return validatePasswordRealTime(value);
    default:
      return { isValid: true, errors: [], warnings: [] };
  }
};

// Enhanced validation functions for real-time feedback
export const validateProjectName = (name) => {
  const errors = [];
  const warnings = [];
  
  if (!name || name.trim() === '') {
    errors.push('Nombre del proyecto es requerido');
    return { isValid: false, errors, warnings };
  }
  
  const trimmedName = name.trim();
  
  if (trimmedName.length < 3) {
    errors.push('Nombre del proyecto debe tener al menos 3 caracteres');
  }
  
  if (trimmedName.length > 200) {
    errors.push('Nombre del proyecto no puede exceder 200 caracteres');
  }
  
  // Check for special characters that might cause issues
  const invalidChars = /[<>:"\/\\|?*]/;
  if (invalidChars.test(trimmedName)) {
    errors.push('Nombre del proyecto contiene caracteres no permitidos');
  }
  
  // Warning for very long names
  if (trimmedName.length > 100) {
    warnings.push('Nombre muy largo, considere usar un nombre más corto');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

export const validateFincaName = (name) => {
  const errors = [];
  const warnings = [];
  
  if (!name || name.trim() === '') {
    errors.push('Nombre de la finca es requerido');
    return { isValid: false, errors, warnings };
  }
  
  const trimmedName = name.trim();
  
  if (trimmedName.length < 2) {
    errors.push('Nombre de la finca debe tener al menos 2 caracteres');
  }
  
  if (trimmedName.length > 200) {
    errors.push('Nombre de la finca no puede exceder 200 caracteres');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

export const validateOwnerName = (name) => {
  const errors = [];
  const warnings = [];
  
  if (!name || name.trim() === '') {
    errors.push('Nombre del propietario es requerido');
    return { isValid: false, errors, warnings };
  }
  
  const trimmedName = name.trim();
  
  if (trimmedName.length < 2) {
    errors.push('Nombre del propietario debe tener al menos 2 caracteres');
  }
  
  if (trimmedName.length > 200) {
    errors.push('Nombre del propietario no puede exceder 200 caracteres');
  }
  
  // Check for valid name format (letters, spaces, common punctuation)
  const namePattern = /^[a-zA-ZáéíóúÁÉÍÓÚñÑ\s\.\-']+$/;
  if (!namePattern.test(trimmedName)) {
    errors.push('Nombre del propietario contiene caracteres no válidos');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

export const validateRegentName = (name) => {
  const errors = [];
  const warnings = [];
  
  if (!name || name.trim() === '') {
    errors.push('Nombre del regente forestal es requerido');
    return { isValid: false, errors, warnings };
  }
  
  const trimmedName = name.trim();
  
  if (trimmedName.length < 2) {
    errors.push('Nombre del regente forestal debe tener al menos 2 caracteres');
  }
  
  if (trimmedName.length > 200) {
    errors.push('Nombre del regente forestal no puede exceder 200 caracteres');
  }
  
  // Check for valid name format
  const namePattern = /^[a-zA-ZáéíóúÁÉÍÓÚñÑ\s\.\-']+$/;
  if (!namePattern.test(trimmedName)) {
    errors.push('Nombre del regente forestal contiene caracteres no válidos');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

export const validateDepartment = (department) => {
  const errors = [];
  
  if (!department || department.trim() === '') {
    errors.push('Departamento es requerido');
    return { isValid: false, errors, warnings: [] };
  }
  
  // List of valid Guatemala departments
  const validDepartments = [
    'Alta Verapaz', 'Baja Verapaz', 'Chimaltenango', 'Chiquimula',
    'El Progreso', 'Escuintla', 'Guatemala', 'Huehuetenango',
    'Izabal', 'Jalapa', 'Jutiapa', 'Petén', 'Quetzaltenango',
    'Quiché', 'Retalhuleu', 'Sacatepéquez', 'San Marcos',
    'Santa Rosa', 'Sololá', 'Suchitepéquez', 'Totonicapán', 'Zacapa'
  ];
  
  if (!validDepartments.includes(department)) {
    errors.push('Seleccione un departamento válido de Guatemala');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings: []
  };
};

export const validateMunicipality = (municipality) => {
  const errors = [];
  
  if (!municipality || municipality.trim() === '') {
    errors.push('Municipio es requerido');
    return { isValid: false, errors, warnings: [] };
  }
  
  const trimmedMunicipality = municipality.trim();
  
  if (trimmedMunicipality.length < 2) {
    errors.push('Municipio debe tener al menos 2 caracteres');
  }
  
  if (trimmedMunicipality.length > 100) {
    errors.push('Municipio no puede exceder 100 caracteres');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings: []
  };
};

export const validateVillage = (village) => {
  const errors = [];
  
  if (!village || village.trim() === '') {
    errors.push('Aldea es requerida');
    return { isValid: false, errors, warnings: [] };
  }
  
  const trimmedVillage = village.trim();
  
  if (trimmedVillage.length < 2) {
    errors.push('Aldea debe tener al menos 2 caracteres');
  }
  
  if (trimmedVillage.length > 100) {
    errors.push('Aldea no puede exceder 100 caracteres');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings: []
  };
};

export const validateRodalNameRealTime = (name, existingNames = []) => {
  const errors = [];
  const warnings = [];
  
  if (!name || name.trim() === '') {
    errors.push('Nombre del rodal es requerido');
    return { isValid: false, errors, warnings };
  }
  
  const trimmedName = name.trim();
  
  if (trimmedName.length < 2) {
    errors.push('Nombre del rodal debe tener al menos 2 caracteres');
  }
  
  if (trimmedName.length > 100) {
    errors.push('Nombre del rodal no puede exceder 100 caracteres');
  }
  
  // Check for uniqueness
  if (existingNames && existingNames.includes(trimmedName)) {
    errors.push('Ya existe un rodal con este nombre en el proyecto');
  }
  
  // Format validation
  const formatRegex = /^[a-zA-Z0-9\s\-_áéíóúÁÉÍÓÚñÑ]+$/;
  if (!formatRegex.test(trimmedName)) {
    errors.push('El nombre solo puede contener letras, números, espacios, guiones y guiones bajos');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

export const validateAreaRealTime = (area) => {
  const errors = [];
  const warnings = [];
  
  if (!area || area === '') {
    errors.push('Área es requerida');
    return { isValid: false, errors, warnings };
  }
  
  const areaValue = parseFloat(area);
  
  if (isNaN(areaValue)) {
    errors.push('Área debe ser un número válido');
    return { isValid: false, errors, warnings };
  }
  
  if (areaValue <= 0) {
    errors.push('Área debe ser mayor que 0');
  }
  
  if (areaValue > 10000) {
    errors.push('Área no puede exceder 10,000 hectáreas');
  }
  
  // Warnings for unusual areas
  if (areaValue < 0.1) {
    warnings.push('Área muy pequeña para inventario forestal (< 0.1 ha)');
  } else if (areaValue > 1000) {
    warnings.push('Área muy grande, considere dividir en múltiples rodales (> 1000 ha)');
  }
  
  // Precision warning
  if (area.toString().includes('.') && area.toString().split('.')[1].length > 4) {
    warnings.push('Se recomienda usar máximo 4 decimales para el área');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

export const validateEmailRealTime = (email) => {
  const errors = [];
  const warnings = [];
  
  if (!email || email.trim() === '') {
    errors.push('Email es requerido');
    return { isValid: false, errors, warnings };
  }
  
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(email)) {
    errors.push('Formato de email inválido');
  }
  
  if (email.length > 100) {
    errors.push('Email no puede exceder 100 caracteres');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

export const validatePasswordRealTime = (password) => {
  const errors = [];
  const warnings = [];
  
  if (!password) {
    errors.push('Contraseña es requerida');
    return { isValid: false, errors, warnings };
  }
  
  if (password.length < 8) {
    errors.push('Contraseña debe tener al menos 8 caracteres');
  }
  
  if (password.length > 100) {
    errors.push('Contraseña no puede exceder 100 caracteres');
  }
  
  // Check for complexity
  const hasUpperCase = /[A-Z]/.test(password);
  const hasLowerCase = /[a-z]/.test(password);
  const hasNumbers = /\d/.test(password);
  const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password);
  
  if (!hasUpperCase) {
    warnings.push('Se recomienda incluir al menos una letra mayúscula');
  }
  
  if (!hasLowerCase) {
    warnings.push('Se recomienda incluir al menos una letra minúscula');
  }
  
  if (!hasNumbers) {
    warnings.push('Se recomienda incluir al menos un número');
  }
  
  if (!hasSpecialChar) {
    warnings.push('Se recomienda incluir al menos un carácter especial');
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

// Data integrity validation functions for sync operations
export const validateSyncDataIntegrity = (records) => {
  const errors = [];
  const warnings = [];
  const validRecords = [];
  const invalidRecords = [];
  
  if (!Array.isArray(records) || records.length === 0) {
    errors.push('No hay registros para sincronizar');
    return { isValid: false, errors, warnings, validRecords, invalidRecords };
  }
  
  records.forEach((record, index) => {
    const recordErrors = [];
    const recordWarnings = [];
    
    // Validate required fields
    const requiredFields = [
      'rodalId', 'numeroParcela', 'fechaCaptura', 'latitud', 
      'longitud', 'especieId', 'dapCm', 'alturaM', 'condicionArbol'
    ];
    
    requiredFields.forEach(field => {
      if (record[field] === null || record[field] === undefined || record[field] === '') {
        recordErrors.push(`Campo requerido faltante: ${field}`);
      }
    });
    
    // Validate data types and ranges
    if (record.rodalId && (!Number.isInteger(record.rodalId) || record.rodalId <= 0)) {
      recordErrors.push('ID de rodal debe ser un número entero positivo');
    }
    
    if (record.numeroParcela && (!Number.isInteger(record.numeroParcela) || record.numeroParcela <= 0)) {
      recordErrors.push('Número de parcela debe ser un número entero positivo');
    }
    
    if (record.especieId && (!Number.isInteger(record.especieId) || record.especieId <= 0)) {
      recordErrors.push('ID de especie debe ser un número entero positivo');
    }
    
    // Validate GPS coordinates
    if (record.latitud !== null && record.latitud !== undefined) {
      const lat = parseFloat(record.latitud);
      if (isNaN(lat) || lat < -90 || lat > 90) {
        recordErrors.push('Latitud debe estar entre -90 y 90 grados');
      } else if (lat < 13 || lat > 18) {
        recordWarnings.push('Coordenadas fuera del territorio de Guatemala');
      }
    }
    
    if (record.longitud !== null && record.longitud !== undefined) {
      const lng = parseFloat(record.longitud);
      if (isNaN(lng) || lng < -180 || lng > 180) {
        recordErrors.push('Longitud debe estar entre -180 y 180 grados');
      } else if (lng < -93 || lng > -88) {
        recordWarnings.push('Coordenadas fuera del territorio de Guatemala');
      }
    }
    
    // Validate DAP
    if (record.dapCm !== null && record.dapCm !== undefined) {
      const dap = parseFloat(record.dapCm);
      if (isNaN(dap) || dap <= 0 || dap > 500) {
        recordErrors.push('DAP debe estar entre 0.1 y 500 cm');
      } else if (dap > 200) {
        recordWarnings.push(`DAP muy grande (${dap} cm) en registro ${index + 1}`);
      } else if (dap < 5) {
        recordWarnings.push(`DAP muy pequeño (${dap} cm) en registro ${index + 1}`);
      }
    }
    
    // Validate height
    if (record.alturaM !== null && record.alturaM !== undefined) {
      const height = parseFloat(record.alturaM);
      if (isNaN(height) || height <= 0 || height > 100) {
        recordErrors.push('Altura debe estar entre 0.1 y 100 m');
      } else if (height > 60) {
        recordWarnings.push(`Altura muy grande (${height} m) en registro ${index + 1}`);
      } else if (height < 1) {
        recordWarnings.push(`Altura muy pequeña (${height} m) en registro ${index + 1}`);
      }
    }
    
    // Validate tree condition
    const validConditions = ['Sano', 'Bifurcado', 'Plagado', 'Muerto en Pie'];
    if (record.condicionArbol && !validConditions.includes(record.condicionArbol)) {
      recordErrors.push(`Condición de árbol inválida: ${record.condicionArbol}`);
    }
    
    // Validate date format
    if (record.fechaCaptura) {
      const date = new Date(record.fechaCaptura);
      if (isNaN(date.getTime())) {
        recordErrors.push('Fecha de captura inválida');
      } else if (date > new Date()) {
        recordErrors.push('Fecha de captura no puede ser futura');
      }
    }
    
    // Add record to appropriate array
    if (recordErrors.length === 0) {
      validRecords.push({
        ...record,
        warnings: recordWarnings,
        index: index + 1
      });
    } else {
      invalidRecords.push({
        ...record,
        errors: recordErrors,
        warnings: recordWarnings,
        index: index + 1
      });
    }
  });
  
  // Add summary errors and warnings
  if (invalidRecords.length > 0) {
    errors.push(`${invalidRecords.length} registros contienen errores y no se pueden sincronizar`);
  }
  
  if (validRecords.length === 0 && records.length > 0) {
    errors.push('Ningún registro es válido para sincronización');
  }
  
  const totalWarnings = validRecords.reduce((acc, record) => acc + record.warnings.length, 0);
  if (totalWarnings > 0) {
    warnings.push(`${totalWarnings} advertencias encontradas en los registros válidos`);
  }
  
  return {
    isValid: validRecords.length > 0,
    errors,
    warnings,
    validRecords,
    invalidRecords,
    summary: {
      total: records.length,
      valid: validRecords.length,
      invalid: invalidRecords.length,
      warningsCount: totalWarnings
    }
  };
};

// Validate batch consistency for sync operations
export const validateBatchConsistency = (batch) => {
  const errors = [];
  const warnings = [];
  
  if (!batch || !batch.records || !Array.isArray(batch.records)) {
    errors.push('Lote de datos inválido');
    return { isValid: false, errors, warnings };
  }
  
  const { records, rodalId } = batch;
  
  // Check if all records belong to the same rodal
  const inconsistentRecords = records.filter(record => record.rodalId !== rodalId);
  if (inconsistentRecords.length > 0) {
    errors.push(`${inconsistentRecords.length} registros no pertenecen al rodal especificado`);
  }
  
  // Check for duplicate plot numbers within the batch
  const plotNumbers = records.map(record => record.numeroParcela);
  const duplicatePlots = plotNumbers.filter((plot, index) => plotNumbers.indexOf(plot) !== index);
  if (duplicatePlots.length > 0) {
    warnings.push(`Números de parcela duplicados en el lote: ${[...new Set(duplicatePlots)].join(', ')}`);
  }
  
  // Check for temporal consistency (all records should be from similar time periods)
  const dates = records.map(record => new Date(record.fechaCaptura)).filter(date => !isNaN(date.getTime()));
  if (dates.length > 1) {
    const minDate = new Date(Math.min(...dates));
    const maxDate = new Date(Math.max(...dates));
    const daysDiff = (maxDate - minDate) / (1000 * 60 * 60 * 24);
    
    if (daysDiff > 30) {
      warnings.push(`Registros del lote abarcan ${Math.round(daysDiff)} días, verifique la consistencia temporal`);
    }
  }
  
  // Check for GPS coordinate clustering (records should be geographically close)
  const coordinates = records
    .filter(record => record.latitud && record.longitud)
    .map(record => ({ lat: parseFloat(record.latitud), lng: parseFloat(record.longitud) }));
  
  if (coordinates.length > 1) {
    const distances = [];
    for (let i = 0; i < coordinates.length - 1; i++) {
      for (let j = i + 1; j < coordinates.length; j++) {
        const distance = calculateDistance(coordinates[i], coordinates[j]);
        distances.push(distance);
      }
    }
    
    const maxDistance = Math.max(...distances);
    if (maxDistance > 5) { // 5 km threshold
      warnings.push(`Registros del lote están muy dispersos geográficamente (máx: ${maxDistance.toFixed(2)} km)`);
    }
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    warnings
  };
};

// Helper function to calculate distance between two GPS coordinates
const calculateDistance = (coord1, coord2) => {
  const R = 6371; // Earth's radius in kilometers
  const dLat = (coord2.lat - coord1.lat) * Math.PI / 180;
  const dLng = (coord2.lng - coord1.lng) * Math.PI / 180;
  const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(coord1.lat * Math.PI / 180) * Math.cos(coord2.lat * Math.PI / 180) *
    Math.sin(dLng / 2) * Math.sin(dLng / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return R * c;
};

// Comprehensive form validation with enhanced error messages
export const validateFormComprehensive = (formType, formData, additionalData = {}) => {
  switch (formType) {
    case 'project':
      return validateProjectFormComprehensive(formData);
    case 'rodal':
      return validateRodalFormComprehensive(formData, additionalData.existingRodales);
    case 'tree':
      return validateTreeFormComprehensive(formData);
    case 'user':
      return validateUserFormComprehensive(formData);
    default:
      return {
        isValid: false,
        errors: { general: 'Tipo de formulario no reconocido' },
        warnings: {},
        fieldValidations: {}
      };
  }
};

export const validateProjectFormComprehensive = (formData) => {
  const errors = {};
  const warnings = {};
  const fieldValidations = {};
  
  // Validate each field individually
  const fields = [
    'nombreProyecto', 'nombreFinca', 'nombrePropietario', 
    'nombreRegenteForestal', 'departamento', 'municipio', 'aldea'
  ];
  
  fields.forEach(field => {
    const validation = validateFieldRealTime(field, formData[field]);
    fieldValidations[field] = validation;
    
    if (!validation.isValid) {
      errors[field] = validation.errors[0];
    }
    
    if (validation.warnings && validation.warnings.length > 0) {
      warnings[field] = validation.warnings;
    }
  });
  
  // Cross-field validations
  if (formData.nombrePropietario && formData.nombreRegenteForestal) {
    if (formData.nombrePropietario.toLowerCase() === formData.nombreRegenteForestal.toLowerCase()) {
      warnings.nombreRegenteForestal = warnings.nombreRegenteForestal || [];
      warnings.nombreRegenteForestal.push('El propietario y regente forestal son la misma persona');
    }
  }
  
  return {
    isValid: Object.keys(errors).length === 0,
    errors,
    warnings,
    fieldValidations
  };
};

export const validateRodalFormComprehensive = (formData, existingRodales = []) => {
  const errors = {};
  const warnings = {};
  const fieldValidations = {};
  
  // Validate rodal name
  const existingNames = existingRodales.map(r => r.nombre_rodal || r.nombreRodal);
  const nameValidation = validateFieldRealTime('nombreRodal', formData.nombreRodal, { existingNames });
  fieldValidations.nombreRodal = nameValidation;
  
  if (!nameValidation.isValid) {
    errors.nombreRodal = nameValidation.errors[0];
  }
  
  // Validate area
  const areaValidation = validateFieldRealTime('areaHa', formData.areaHa);
  fieldValidations.areaHa = areaValidation;
  
  if (!areaValidation.isValid) {
    errors.areaHa = areaValidation.errors[0];
  }
  
  if (areaValidation.warnings && areaValidation.warnings.length > 0) {
    warnings.areaHa = areaValidation.warnings;
  }
  
  // Check total project area if we have existing rodales
  if (existingRodales.length > 0 && formData.areaHa) {
    const totalExistingArea = existingRodales.reduce((sum, rodal) => {
      return sum + parseFloat(rodal.area_ha || rodal.areaHa || 0);
    }, 0);
    
    const newArea = parseFloat(formData.areaHa);
    const totalArea = totalExistingArea + newArea;
    
    if (totalArea > 5000) {
      warnings.areaHa = warnings.areaHa || [];
      warnings.areaHa.push(`Área total del proyecto será ${totalArea.toFixed(2)} ha, considere si es apropiado`);
    }
  }
  
  return {
    isValid: Object.keys(errors).length === 0,
    errors,
    warnings,
    fieldValidations
  };
};

export const validateTreeFormComprehensive = (formData) => {
  const errors = {};
  const warnings = {};
  const fieldValidations = {};
  
  // Validate each field
  const fields = ['numeroParcela', 'dapCm', 'alturaM', 'condicionArbol'];
  
  fields.forEach(field => {
    const validation = validateFieldRealTime(field, formData[field]);
    fieldValidations[field] = validation;
    
    if (!validation.isValid) {
      errors[field] = validation.errors[0];
    }
    
    if (validation.warnings && validation.warnings.length > 0) {
      warnings[field] = validation.warnings;
    }
  });
  
  // Validate species selection
  if (!formData.especieId || formData.especieId === '') {
    errors.especieId = 'Debe seleccionar una especie';
  }
  
  // Cross-field validations (DAP vs Height relationship)
  if (formData.dapCm && formData.alturaM) {
    const dap = parseFloat(formData.dapCm);
    const height = parseFloat(formData.alturaM);
    
    if (!isNaN(dap) && !isNaN(height)) {
      // Check for unrealistic DAP/Height ratios
      const ratio = height / (dap / 100); // height in m / diameter in m
      
      if (ratio < 5) {
        warnings.alturaM = warnings.alturaM || [];
        warnings.alturaM.push('Altura parece baja en relación al DAP');
      } else if (ratio > 50) {
        warnings.dapCm = warnings.dapCm || [];
        warnings.dapCm.push('DAP parece pequeño en relación a la altura');
      }
    }
  }
  
  return {
    isValid: Object.keys(errors).length === 0,
    errors,
    warnings,
    fieldValidations
  };
};

export const validateUserFormComprehensive = (formData) => {
  const errors = {};
  const warnings = {};
  const fieldValidations = {};
  
  // Validate email
  const emailValidation = validateFieldRealTime('email', formData.email);
  fieldValidations.email = emailValidation;
  
  if (!emailValidation.isValid) {
    errors.email = emailValidation.errors[0];
  }
  
  // Validate password if provided
  if (formData.password) {
    const passwordValidation = validateFieldRealTime('password', formData.password);
    fieldValidations.password = passwordValidation;
    
    if (!passwordValidation.isValid) {
      errors.password = passwordValidation.errors[0];
    }
    
    if (passwordValidation.warnings && passwordValidation.warnings.length > 0) {
      warnings.password = passwordValidation.warnings;
    }
  }
  
  // Validate name
  if (!formData.nombre || formData.nombre.trim() === '') {
    errors.nombre = 'Nombre es requerido';
  } else if (formData.nombre.trim().length < 2) {
    errors.nombre = 'Nombre debe tener al menos 2 caracteres';
  }
  
  // Validate role
  const validRoles = ['Administrador', 'Regente', 'Técnico de Campo'];
  if (!formData.rol || !validRoles.includes(formData.rol)) {
    errors.rol = 'Debe seleccionar un rol válido';
  }
  
  return {
    isValid: Object.keys(errors).length === 0,
    errors,
    warnings,
    fieldValidations
  };
};

// Enhanced error message generator
export const generateErrorMessage = (field, error, context = {}) => {
  const errorMessages = {
    required: `${field} es un campo obligatorio`,
    invalid_format: `${field} tiene un formato inválido`,
    too_short: `${field} es demasiado corto`,
    too_long: `${field} es demasiado largo`,
    out_of_range: `${field} está fuera del rango permitido`,
    duplicate: `${field} ya existe`,
    invalid_type: `${field} debe ser del tipo correcto`
  };
  
  // Return custom message if available, otherwise use default
  return errorMessages[error] || `Error en ${field}: ${error}`;
};

// Validation summary generator
export const generateValidationSummary = (validationResult) => {
  const { isValid, errors, warnings, fieldValidations } = validationResult;
  
  const summary = {
    isValid,
    errorCount: Object.keys(errors).length,
    warningCount: Object.values(warnings).flat().length,
    fieldsWithErrors: Object.keys(errors),
    fieldsWithWarnings: Object.keys(warnings),
    totalFields: Object.keys(fieldValidations || {}).length
  };
  
  // Generate human-readable summary
  if (summary.isValid) {
    summary.message = summary.warningCount > 0 
      ? `Formulario válido con ${summary.warningCount} advertencia(s)`
      : 'Formulario completamente válido';
  } else {
    summary.message = `Formulario inválido: ${summary.errorCount} error(es) encontrado(s)`;
  }
  
  return summary;
};