export type ValidationResult = {
  isValid: boolean;
  message: string;
  type: 'ipv4' | 'ipv6' | 'cidr-v4' | 'cidr-v6' | 'none';
};

// Utility functions for IP address validation
const isIPv4Segment = (segment: string): boolean => {
  const num = Number(segment);
  return !isNaN(num) && num >= 0 && num <= 255 && segment === num.toString();
};

const isIPv4Address = (address: string): boolean => {
  const segments = address.split('.');
  return segments.length === 4 && segments.every(isIPv4Segment);
};

const isIPv6Segment = (segment: string): boolean => {
  return segment.length <= 4 && /^[0-9a-fA-F]*$/.test(segment);
};

const isIPv6Address = (address: string): boolean => {
  // Handle the :: compression
  const parts = address.split('::');
  if (parts.length > 2) return false; // More than one :: is invalid

  if (parts.length === 2) {
    const [left, right] = parts;
    const leftSegments = left ? left.split(':') : [];
    const rightSegments = right ? right.split(':') : [];

    // Total segments should be 8 after decompression
    if (leftSegments.length + rightSegments.length > 7) return false;

    // Validate each segment
    return (
      leftSegments.every(isIPv6Segment) && rightSegments.every(isIPv6Segment)
    );
  }

  // No compression, should be exactly 8 segments
  const segments = address.split(':');
  return segments.length === 8 && segments.every(isIPv6Segment);
};

const isCIDRPrefix = (prefix: string, isIPv6: boolean): boolean => {
  const num = Number(prefix);
  return !isNaN(num) && num >= 0 && num <= (isIPv6 ? 128 : 32);
};

const validateCIDR = (input: string): ValidationResult | null => {
  const [address, prefix] = input.split('/');
  if (!prefix) return null;

  // Check if it's IPv6 CIDR
  if (address.includes(':')) {
    if (!isIPv6Address(address) || !isCIDRPrefix(prefix, true)) {
      return {
        isValid: false,
        message: 'Invalid IPv6 CIDR range format',
        type: 'none',
      };
    }
    return {
      isValid: true,
      message: 'Valid IPv6 CIDR range',
      type: 'cidr-v6',
    };
  }

  // Check if it's IPv4 CIDR
  if (!isIPv4Address(address) || !isCIDRPrefix(prefix, false)) {
    return {
      isValid: false,
      message: 'Invalid IPv4 CIDR range format',
      type: 'none',
    };
  }
  return {
    isValid: true,
    message: 'Valid IPv4 CIDR range',
    type: 'cidr-v4',
  };
};

export const validateIpAddress = (input: string): ValidationResult => {
  if (!input) {
    return {
      isValid: false,
      message: 'IP address is required',
      type: 'none',
    };
  }

  if (input.includes('/')) {
    const cidrResult = validateCIDR(input);
    if (cidrResult) return cidrResult;

    return {
      isValid: false,
      message: 'Invalid CIDR range format',
      type: 'none',
    };
  }

  // Single IP address validation
  if (isIPv4Address(input)) {
    return {
      isValid: true,
      message: 'Valid IPv4 address',
      type: 'ipv4',
    };
  }

  if (isIPv6Address(input)) {
    return {
      isValid: true,
      message: 'Valid IPv6 address',
      type: 'ipv6',
    };
  }

  return {
    isValid: false,
    message: 'Invalid IP address format',
    type: 'none',
  };
};
