// Shared task list filter/sort/count logic, used by both the Tasks page
// (TaskListPanel) and the per-space chat list (SpaceDetail) so search,
// status filtering, and sorting behave identically in both places.
import { LocalTask } from '../api';
import { matchText } from './utils';
import { COLUMN_LIST, SortMode, StatusColumn } from './urlState';

/**
 * Whether a task matches a free-text query across title / body / piece / owner
 * name. The single source of truth for the list search predicate — reused by
 * the list, rail, and space views so the searchable field set never drifts.
 * An empty/whitespace query matches everything (matchText returns true).
 */
export function taskMatchesQuery(t: LocalTask, query: string): boolean {
  return (
    matchText(t.title, query) ||
    matchText(t.body, query) ||
    matchText(t.pieceName, query) ||
    matchText(t.ownerName ?? '', query)
  );
}

/** Group tasks by their latest job status (defaulting to 'queued'). */
export function groupTasksByStatus(tasks: LocalTask[]): Record<string, LocalTask[]> {
  return COLUMN_LIST.reduce((acc, s) => {
    acc[s] = tasks.filter(t => (t.latestJob?.status ?? 'queued') === s);
    return acc;
  }, {} as Record<string, LocalTask[]>);
}

/** Per-status counts from a grouped map (every COLUMN_LIST key present). */
export function statusCounts(columns: Record<string, LocalTask[]>): Record<string, number> {
  const counts: Record<string, number> = {};
  for (const s of COLUMN_LIST) counts[s] = columns[s]?.length ?? 0;
  return counts;
}

/** Total across all status columns (matches what the status tabs sum to). */
export function totalTaskCount(columns: Record<string, LocalTask[]>): number {
  return Object.values(columns).flat().length;
}

/**
 * Apply the status filter, free-text search (title / body / piece / owner
 * name), and sort. Mirrors the Tasks page list behavior exactly.
 */
export function filterAndSortTasks(
  tasks: LocalTask[],
  selectedStatus: 'all' | StatusColumn,
  searchQuery: string,
  sortMode: SortMode,
): LocalTask[] {
  const columns = groupTasksByStatus(tasks);
  const all = Object.values(columns).flat();
  const base = selectedStatus === 'all' ? all : columns[selectedStatus] ?? [];
  return base
    .filter(t => taskMatchesQuery(t, searchQuery))
    .sort((a, b) => {
      if (sortMode === 'title') return a.title.localeCompare(b.title);
      if (sortMode === 'status') {
        const as = a.latestJob?.status ?? 'queued';
        const bs = b.latestJob?.status ?? 'queued';
        return as.localeCompare(bs);
      }
      return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
    });
}
