import { Task, TaskPriority } from './types';
import { getPriorityConfig } from './status-config';

export type SortField =
  | 'priority'
  | 'tags'
  | 'createdAt'
  | 'updatedAt'
  | 'dueDate'
  | 'title';
export type SortDirection = 'asc' | 'desc';

export interface SortConfig {
  field: SortField;
  direction: SortDirection;
}

export interface SortOption {
  key: string;
  label: string;
  field: SortField;
  direction: SortDirection;
  iconName: string;
}

// Configuration des options de tri disponibles
export const SORT_OPTIONS: SortOption[] = [
  {
    key: 'priority-desc',
    label: 'Priorité (Urgente → Faible)',
    field: 'priority',
    direction: 'desc',
    iconName: 'flame',
  },
  {
    key: 'priority-asc',
    label: 'Priorité (Faible → Urgente)',
    field: 'priority',
    direction: 'asc',
    iconName: 'circle',
  },
  {
    key: 'tags-asc',
    label: 'Tags (A → Z)',
    field: 'tags',
    direction: 'asc',
    iconName: 'tag',
  },
  {
    key: 'title-asc',
    label: 'Titre (A → Z)',
    field: 'title',
    direction: 'asc',
    iconName: 'file-text',
  },
  {
    key: 'title-desc',
    label: 'Titre (Z → A)',
    field: 'title',
    direction: 'desc',
    iconName: 'file-text',
  },
  {
    key: 'createdAt-desc',
    label: 'Date création (Récent → Ancien)',
    field: 'createdAt',
    direction: 'desc',
    iconName: 'calendar',
  },
  {
    key: 'createdAt-asc',
    label: 'Date création (Ancien → Récent)',
    field: 'createdAt',
    direction: 'asc',
    iconName: 'calendar',
  },
  {
    key: 'dueDate-asc',
    label: 'Échéance (Proche → Lointaine)',
    field: 'dueDate',
    direction: 'asc',
    iconName: 'clock',
  },
  {
    key: 'dueDate-desc',
    label: 'Échéance (Lointaine → Proche)',
    field: 'dueDate',
    direction: 'desc',
    iconName: 'clock',
  },
];

// Tri par défaut : Priorité (desc) puis Tags (asc)
export const DEFAULT_SORT: SortConfig[] = [
  { field: 'priority', direction: 'desc' },
  { field: 'tags', direction: 'asc' },
];

/**
 * Compare deux valeurs selon la direction de tri
 */
function compareValues<T>(a: T, b: T, direction: SortDirection): number {
  if (a === b) return 0;
  if (a == null) return 1;
  if (b == null) return -1;

  const result = a < b ? -1 : 1;
  return direction === 'asc' ? result : -result;
}

/**
 * Obtient la valeur de priorité numérique pour le tri
 */
function getPriorityValue(priority: TaskPriority): number {
  const config = getPriorityConfig(priority);
  if (!config) {
    console.warn(
      `⚠️ Priorité inconnue: ${priority}, utilisation de 'medium' par défaut`
    );
    return getPriorityConfig('medium').order;
  }
  return config.order;
}

/**
 * Obtient le premier tag pour le tri (ou chaîne vide si pas de tags)
 */
function getFirstTag(task: Task): string {
  return task.tags?.[0]?.toLowerCase() || '';
}

/**
 * Compare deux tâches selon un critère de tri
 */
function compareTasksByField(a: Task, b: Task, sortConfig: SortConfig): number {
  const { field, direction } = sortConfig;

  switch (field) {
    case 'priority':
      return compareValues(
        getPriorityValue(a.priority),
        getPriorityValue(b.priority),
        direction
      );

    case 'tags':
      return compareValues(getFirstTag(a), getFirstTag(b), direction);

    case 'title':
      return compareValues(
        a.title.toLowerCase(),
        b.title.toLowerCase(),
        direction
      );

    case 'createdAt':
      return compareValues(
        a.createdAt.getTime(),
        b.createdAt.getTime(),
        direction
      );

    case 'updatedAt':
      return compareValues(
        a.updatedAt.getTime(),
        b.updatedAt.getTime(),
        direction
      );

    case 'dueDate':
      return compareValues(
        a.dueDate ? a.dueDate.getTime() : null,
        b.dueDate ? b.dueDate.getTime() : null,
        direction
      );

    default:
      return 0;
  }
}

/**
 * Trie un tableau de tâches selon une configuration de tri multiple
 */
export function sortTasks(
  tasks: Task[],
  sortConfigs: SortConfig[] = DEFAULT_SORT
): Task[] {
  return [...tasks].sort((a, b) => {
    for (const sortConfig of sortConfigs) {
      const result = compareTasksByField(a, b, sortConfig);
      if (result !== 0) {
        return result;
      }
    }
    return 0;
  });
}

/**
 * Utilitaire pour obtenir une option de tri par sa clé
 */
export function getSortOption(key: string): SortOption | undefined {
  return SORT_OPTIONS.find((option) => option.key === key);
}

/**
 * Utilitaire pour créer une clé de tri
 */
export function createSortKey(
  field: SortField,
  direction: SortDirection
): string {
  return `${field}-${direction}`;
}
