import { DEFAULT_MIN_AGE, DEFAULT_MAX_AGE } from '../constants/age-range.constants';

/**
 * Regular expressions for parsing age range formats
 */
export const AGE_RANGE_PATTERNS = {
  /** Matches: <=4, <=18, <=100 */
  LESS_THAN_OR_EQUAL: /^<=\d+$/,
  /** Matches: <4, <18, <100 */
  LESS_THAN: /^<\d+$/,
  /** Matches: >=4, >=18, >=100 */
  GREATER_THAN_OR_EQUAL: /^>=\d+$/,
  /** Matches: >4, >18, >100 */
  GREATER_THAN: /^>\d+$/,
  /** Matches: 4-7, 19-29, 100-120 (with or without spaces) */
  RANGE: /^(\d+)-(\d+)$/,
};

/**
 * Interface for parsed age range
 */
export interface ParsedAgeRange {
  minAge: number;
  maxAge: number;
  matched: boolean;
}

/**
 * Parses an age range string into min and max age values
 * Supports formats: '<=18', '>=60', '19-29', '19 - 29'
 * 
 * @param range - The age range string to parse
 * @returns ParsedAgeRange object with minAge, maxAge, and matched flag
 * 
 * @example
 * parseAgeRange('<=18')    // { minAge: 0, maxAge: 18, matched: true }
 * parseAgeRange('>=60')    // { minAge: 60, maxAge: 200, matched: true }
 * parseAgeRange('19-29')   // { minAge: 19, maxAge: 29, matched: true }
 * parseAgeRange('invalid') // { minAge: 0, maxAge: 200, matched: false }
 */
export function parseAgeRange(range: string): ParsedAgeRange {
  let minAge: number = DEFAULT_MIN_AGE;
  let maxAge: number = DEFAULT_MAX_AGE;
  let matched = false;

  // Remove all whitespace for consistent parsing
  const trimmed = range.replace(/\s/g, '');

  // <=N
  if (AGE_RANGE_PATTERNS.LESS_THAN_OR_EQUAL.test(trimmed)) {
    maxAge = parseInt(trimmed.replace(/[^\d]/g, ''));
    minAge = DEFAULT_MIN_AGE;
    matched = true;
  }
  // <N
  else if (AGE_RANGE_PATTERNS.LESS_THAN.test(trimmed)) {
    maxAge = parseInt(trimmed.replace(/[^\d]/g, '')) - 1;
    minAge = DEFAULT_MIN_AGE;
    matched = true;
  }
  // >=N
  else if (AGE_RANGE_PATTERNS.GREATER_THAN_OR_EQUAL.test(trimmed)) {
    minAge = parseInt(trimmed.replace(/[^\d]/g, ''));
    maxAge = DEFAULT_MAX_AGE;
    matched = true;
  }
  // >N
  else if (AGE_RANGE_PATTERNS.GREATER_THAN.test(trimmed)) {
    minAge = parseInt(trimmed.replace(/[^\d]/g, '')) + 1;
    maxAge = DEFAULT_MAX_AGE;
    matched = true;
  }
  // N-M
  else if (AGE_RANGE_PATTERNS.RANGE.test(trimmed)) {
    const match = trimmed.match(/(\d+)-(\d+)/);
    if (match && match[1] && match[2]) {
      minAge = parseInt(match[1]);
      maxAge = parseInt(match[2]);
      matched = true;
    }
  }

  return { minAge, maxAge, matched };
}

/**
 * Converts age range to birth date range for database queries
 * 
 * @param minAge - Minimum age in the range
 * @param maxAge - Maximum age in the range
 * @param currentDate - Reference date for calculation (defaults to now)
 * @returns Object with minBirthDate and maxBirthDate
 * 
 * @example
 * // For age range 19-29:
 * // maxBirthDate: person born on this date would be 19 years old today
 * // minBirthDate: person born on this date would be 29 years old today
 */
export function ageToBirthDateRange(
  minAge: number,
  maxAge: number,
  currentDate: Date = new Date(),
): { minBirthDate: Date; maxBirthDate: Date } {
  // maxBirthDate: person born on this date would be minAge years old today
  const maxBirthDate = new Date(
    currentDate.getFullYear() - minAge,
    currentDate.getMonth(),
    currentDate.getDate(),
  );

  // minBirthDate: person born on this date would be maxAge years old today
  const minBirthDate = new Date(
    currentDate.getFullYear() - maxAge - 1,
    currentDate.getMonth(),
    currentDate.getDate(),
  );

  return { minBirthDate, maxBirthDate };
}
