/**
 * Category sorting utility for sorting competition categories by age groups
 * Priority order: Muži first, then descending U-numbers (U19, U17, U15, etc.)
 */

export interface CategoryItem {
  name: string;
  alias?: string;
  code?: string;
  [key: string]: any;
}

/**
 * Extracts the U-number from a category name/alias
 * @param text - Category name or alias
 * @returns The U-number (e.g., 19 from "U19") or null if not found
 */
function extractUNumber(text: string): number | null {
  if (!text) return null;
  
  // Look for U followed by digits (U19, U17, U15, etc.)
  const match = text.match(/\bU(\d+)\b/i);
  if (match) {
    return parseInt(match[1], 10);
  }
  
  return null;
}

/**
 * Checks if a category is for "Muži" (Men/Adults)
 * @param text - Category name or alias
 * @returns true if this is a men's/adults category
 */
function isMuzi(text: string): boolean {
  if (!text) return false;
  
  const normalized = text
    .toLowerCase()
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, ''); // Remove diacritics
  
  // Check for common terms for adult/men's teams
  return /\b(muzi|muž|muze|dospeli|dospělí|a[\s-]?team|a[\s-]?tym|senior)\b/i.test(normalized);
}

/**
 * Gets the sort priority for a category
 * Lower numbers = higher priority (sorted first)
 * @param text - Category name or alias
 * @returns Sort priority number
 */
function getSortPriority(text: string): number {
  if (!text) return 9999;
  
  // Muži always first
  if (isMuzi(text)) {
    return 0;
  }
  
  // U-numbers sorted descending (U19 before U17 before U15, etc.)
  const uNumber = extractUNumber(text);
  if (uNumber !== null) {
    // Use 1000 - uNumber so higher numbers come first
    // U19 = 1000 - 19 = 981
    // U17 = 1000 - 17 = 983
    // U15 = 1000 - 15 = 985
    return 1000 - uNumber;
  }
  
  // Everything else goes to the end, sorted alphabetically
  return 2000;
}

/**
 * Comparator function for sorting categories
 * @param a - First category
 * @param b - Second category
 * @returns Comparison result
 */
export function compareCategories<T extends CategoryItem>(a: T, b: T): number {
  // Use alias if available, otherwise use name
  const aText = a.alias || a.name || '';
  const bText = b.alias || b.name || '';
  
  const aPriority = getSortPriority(aText);
  const bPriority = getSortPriority(bText);
  
  // If priorities are different, sort by priority
  if (aPriority !== bPriority) {
    return aPriority - bPriority;
  }
  
  // If both have same priority (both in "other" category), sort alphabetically
  return aText.localeCompare(bText, 'cs');
}

/**
 * Sorts an array of categories by age (Muži first, then U19, U17, etc.)
 * @param categories - Array of categories to sort
 * @returns Sorted array (new array, does not mutate original)
 */
export function sortCategories<T extends CategoryItem>(categories: T[]): T[] {
  return [...categories].sort(compareCategories);
}

/**
 * Sorts categories with a custom order field, falling back to age-based sorting
 * @param categories - Array of categories to sort
 * @param orderField - Name of the field containing custom order (optional)
 * @returns Sorted array
 */
export function sortCategoriesWithOrder<T extends CategoryItem>(
  categories: T[],
  orderField: keyof T = 'display_order' as keyof T
): T[] {
  return [...categories].sort((a, b) => {
    // If both have custom order, use that
    const aOrder = a[orderField] as number | undefined;
    const bOrder = b[orderField] as number | undefined;
    
    if (typeof aOrder === 'number' && typeof bOrder === 'number') {
      if (aOrder !== bOrder) {
        return aOrder - bOrder;
      }
    }
    
    // If only one has custom order, prioritize it
    if (typeof aOrder === 'number') return -1;
    if (typeof bOrder === 'number') return 1;
    
    // Otherwise fall back to age-based sorting
    return compareCategories(a, b);
  });
}
