import { useQuery } from '@tanstack/react-query';
import { useClient } from 'hooks/useClient';

type TriggerConfig = { type: 'file'; extensions: string[] } | { type: 'directory' };

export type TaskSummary = {
  id: number;
  dirName: string;
  name: string;
  description: string;
  scope: string;
  category: string | null;
  triggers: TriggerConfig[];
  mode: 'script' | 'agentic' | 'pipeline';
  userId: number | null;
};

export type TaskGroup = { category: string; tasks: TaskSummary[] };

const UNCATEGORIZED = 'Other';

// Every task carries a `directory` trigger, so right-clicking a folder listed all of them at once.
// Grouping by category turns that into Run Task > Video > …
//
// The order comes from categories.yaml in the items store, not from here — adding a category is a
// change to that file plus the tasks using it, never to this code. Categories absent from the list
// sort alphabetically after the listed ones, and Other is always last.
const categoryRank = (category: string, order: string[]): number => {
  const known = order.indexOf(category);
  if (known !== -1) return known;
  return category === UNCATEGORIZED ? Number.MAX_SAFE_INTEGER : order.length;
};

export const groupTasksByCategory = (tasks: TaskSummary[], order: string[] = []): TaskGroup[] => {
  const groups = new Map<string, TaskSummary[]>();
  for (const task of tasks) {
    const category = task.category?.trim() || UNCATEGORIZED;
    const bucket = groups.get(category);
    if (bucket) bucket.push(task);
    else groups.set(category, [task]);
  }

  return Array.from(groups.entries())
    .map(([category, list]) => ({ category, tasks: [...list].sort((a, b) => a.name.localeCompare(b.name)) }))
    .sort(
      (a, b) =>
        categoryRank(a.category, order) - categoryRank(b.category, order) || a.category.localeCompare(b.category),
    );
};

export const useTasks = () => {
  const client = useClient();

  const { data: tasks = [] } = useQuery<TaskSummary[]>({
    queryKey: ['tasks'],
    queryFn: () => client.get('/tasks'),
    staleTime: 60_000,
  });

  const { data: categoryOrder = [] } = useQuery<string[]>({
    queryKey: ['task-categories'],
    queryFn: () => client.get('/tasks/categories'),
    staleTime: 60_000,
  });

  const getMatchingTasks = (fileName: string, entryType: 'file' | 'directory'): TaskSummary[] => {
    if (entryType === 'directory') {
      return tasks.filter((t) => t.triggers.some((tr) => tr.type === 'directory'));
    }
    const ext = fileName.split('.').pop()?.toLowerCase();
    if (!ext) return [];
    return tasks.filter((t) => t.triggers.some((tr) => tr.type === 'file' && tr.extensions.includes(ext)));
  };

  // Grouped for the context menu, ordered by categories.yaml.
  const getMatchingTaskGroups = (fileName: string, entryType: 'file' | 'directory'): TaskGroup[] =>
    groupTasksByCategory(getMatchingTasks(fileName, entryType), categoryOrder);

  return { tasks, categoryOrder, getMatchingTasks, getMatchingTaskGroups };
};
