const { body } = require('express-validator');

// Validation for creating a new address
exports.validateCreateAddress = [
  body('name')
    .trim()
    .notEmpty().withMessage('Name is required')
    .isLength({ max: 100 }).withMessage('Name cannot exceed 100 characters'),
  
  body('contactNumber')
    .optional()
    .trim()
    .custom((value) => {
      // If a contact number is provided, validate it
      if (value && value.trim() !== '') {
        if (!/^[6-9]\d{9}$/.test(value)) {
          throw new Error('Invalid phone number');
        }
      }
      return true;
    }),
  
  body('postcode')
    .optional({ nullable: true })
    .trim()
    .matches(/^$|^[1-9][0-9]{5}$/).withMessage('Invalid postcode format'),
  
  body('state')
    .trim()
    .notEmpty().withMessage('State is required'),
  
  body('city')
    .trim()
    .notEmpty().withMessage('City is required'),
  
  body('address')
    .trim()
    .notEmpty().withMessage('Address is required'),
  
  body('type')
    .optional()
    .isIn(['home', 'work', 'other']).withMessage('Invalid address type'),
  
  // Validate location coordinates with more flexible approach
  body('location')
    .optional()
    .custom((value) => {
      // If location is provided, validate its structure
      if (value) {
        // Ensure location is an object
        if (typeof value !== 'object') {
          throw new Error('Location must be an object');
        }

        // Check type if provided
        if (value.type && value.type !== 'Point') {
          throw new Error('Invalid location type');
        }

        // Validate coordinates if provided
        if (value.coordinates) {
          // Ensure coordinates is an array
          if (!Array.isArray(value.coordinates)) {
            throw new Error('Coordinates must be an array');
          }

          // Ensure exactly 2 coordinates
          if (value.coordinates.length !== 2) {
            throw new Error('Coordinates must be an array of [longitude, latitude]');
          }

          const [longitude, latitude] = value.coordinates;

          // Convert to numbers and validate
          const lon = Number(longitude);
          const lat = Number(latitude);

          // Check if conversion was successful
          if (isNaN(lon) || isNaN(lat)) {
            throw new Error('Coordinates must be numeric');
          }

          // Validate ranges
          if (lon < -180 || lon > 180) {
            throw new Error('Longitude must be between -180 and 180');
          }

          if (lat < -90 || lat > 90) {
            throw new Error('Latitude must be between -90 and 90');
          }
        }
      }

      return true;
    })
];

// Validation for updating an existing address
exports.validateUpdateAddress = [
  body('name')
    .optional()
    .trim()
    .isLength({ max: 100 }).withMessage('Name cannot exceed 100 characters'),
  
  body('contactNumber')
    .optional()
    .trim()
    .custom((value) => {
      // If a contact number is provided, validate it
      if (value && value.trim() !== '') {
        if (!/^[6-9]\d{9}$/.test(value)) {
          throw new Error('Invalid phone number');
        }
      }
      return true;
    }),
  
  body('postcode')
    .optional()
    .trim()
    .matches(/^[1-9][0-9]{5}$/).withMessage('Invalid postcode'),
  
  body('type')
    .optional()
    .isIn(['home', 'work', 'other']).withMessage('Invalid address type'),
  
  // Validate location coordinates for update with same flexible approach
  body('location')
    .optional()
    .custom((value) => {
      // If location is provided, validate its structure
      if (value) {
        // Ensure location is an object
        if (typeof value !== 'object') {
          throw new Error('Location must be an object');
        }

        // Check type if provided
        if (value.type && value.type !== 'Point') {
          throw new Error('Invalid location type');
        }

        // Validate coordinates if provided
        if (value.coordinates) {
          // Ensure coordinates is an array
          if (!Array.isArray(value.coordinates)) {
            throw new Error('Coordinates must be an array');
          }

          // Ensure exactly 2 coordinates
          if (value.coordinates.length !== 2) {
            throw new Error('Coordinates must be an array of [longitude, latitude]');
          }

          const [longitude, latitude] = value.coordinates;

          // Convert to numbers and validate
          const lon = Number(longitude);
          const lat = Number(latitude);

          // Check if conversion was successful
          if (isNaN(lon) || isNaN(lat)) {
            throw new Error('Coordinates must be numeric');
          }

          // Validate ranges
          if (lon < -180 || lon > 180) {
            throw new Error('Longitude must be between -180 and 180');
          }

          if (lat < -90 || lat > 90) {
            throw new Error('Latitude must be between -90 and 90');
          }
        }
      }

      return true;
    })
];
