// Pure filter/sort logic for the Threads list panel. Operates on plain snapshots
// so it's unit-testable without real matrix-js-sdk Thread objects.

export type ThreadFilter = 'all' | 'unread' | 'participating';
export type ThreadSort = 'recent' | 'oldest';

export type ThreadSnapshot = {
  id: string;
  latestTs: number;
  unread: number;
  participated: boolean;
};

const THREAD_FILTERS: readonly ThreadFilter[] = ['all', 'unread', 'participating'];
const THREAD_SORTS: readonly ThreadSort[] = ['recent', 'oldest'];

/** Type guard for persisted/untrusted filter values (localStorage can hold junk). */
export function isThreadFilter(value: unknown): value is ThreadFilter {
  return typeof value === 'string' && (THREAD_FILTERS as readonly string[]).includes(value);
}

/** Type guard for persisted/untrusted sort values. */
export function isThreadSort(value: unknown): value is ThreadSort {
  return typeof value === 'string' && (THREAD_SORTS as readonly string[]).includes(value);
}

/** Keep only the threads matching the filter. Pure — returns a new array. */
export function filterThreads<T extends ThreadSnapshot>(threads: T[], filter: ThreadFilter): T[] {
  if (filter === 'unread') return threads.filter((t) => t.unread > 0);
  if (filter === 'participating') return threads.filter((t) => t.participated);
  return [...threads];
}

/**
 * Order threads by last activity. `recent` = newest first, `oldest` = oldest first.
 * Ties broken by id for stable, deterministic output. Pure — returns a new array.
 */
export function sortThreads<T extends ThreadSnapshot>(threads: T[], sort: ThreadSort): T[] {
  const idCmp = (a: T, b: T): number => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
  return [...threads].sort((a, b) => {
    const diff = sort === 'oldest' ? a.latestTs - b.latestTs : b.latestTs - a.latestTs;
    return diff !== 0 ? diff : idCmp(a, b);
  });
}
