import { createFileRoute } from '@tanstack/react-router';
import { useState, useCallback, useMemo, useRef, useEffect } from 'react';
import { useFloatingChat } from '@/context/FloatingChatContext';
import {
  ClipboardCheck,
  ListTodo,
  Loader2,
  CheckCircle2,
  Plus,
  Search,
} from 'lucide-react';
import { trpc } from '@/lib/trpc';
import { Item, ItemMedia, ItemContent, ItemTitle, ItemDescription } from '@/components/ui/item';
import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from '@/components/ui/empty';
import { NewTaskDialog } from '@/components/tasks/NewTaskDialog';
import { EditTaskDialog } from '@/components/tasks/EditTaskDialog';
import { TaskDetailDialog } from '@/components/tasks/TaskDetailDialog';
import { TaskRow, type TaskItem } from '@/components/tasks/TaskRow';

export const Route = createFileRoute('/tasks')({
  component: TasksPage,
});

type StatusFilter = 'all' | 'todo' | 'in_progress' | 'done';
type OrderBy = 'dueDate' | 'priority' | 'createdAt';

const ORDER_LABELS: Record<OrderBy, string> = {
  dueDate: 'Due Date',
  priority: 'Priority',
  createdAt: 'Created Date',
};

function TasksPage() {
  // Temporary test: register section for floating AI chat
  const testRef = useRef<HTMLDivElement>(null);
  const { registerSection, unregisterSection } = useFloatingChat();
  useEffect(() => {
    registerSection({ id: 'test', label: 'Tasks', ref: testRef });
    return () => unregisterSection('test');
  }, [registerSection, unregisterSection]);

  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');
  const [orderBy, setOrderBy] = useState<OrderBy>('dueDate');
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editTask, setEditTask] = useState<TaskItem | null>(null);
  const [viewTask, setViewTask] = useState<TaskItem | null>(null);

  const debounceTimer = useMemo(() => ({ id: null as ReturnType<typeof setTimeout> | null }), []);

  const handleSearchChange = useCallback(
    (value: string) => {
      setSearch(value);
      if (debounceTimer.id) clearTimeout(debounceTimer.id);
      debounceTimer.id = setTimeout(() => setDebouncedSearch(value), 300);
    },
    [debounceTimer],
  );

  const queryInput = useMemo(
    () => ({
      ...(statusFilter !== 'all' ? { status: statusFilter as 'todo' | 'in_progress' | 'done' } : {}),
      ...(debouncedSearch.trim() ? { search: debouncedSearch.trim() } : {}),
      orderBy,
    }),
    [statusFilter, debouncedSearch, orderBy],
  );

  const { data: allTasks } = trpc.tasks.list.useQuery({});
  const { data: filteredTasks } = trpc.tasks.list.useQuery(queryInput);
  const utils = trpc.useUtils();

  const updateTask = trpc.tasks.update.useMutation({
    onSuccess: () => {
      void utils.tasks.list.invalidate();
    },
  });

  const deleteTask = trpc.tasks.delete.useMutation({
    onSuccess: () => {
      void utils.tasks.list.invalidate();
    },
  });

  const tasksList = (filteredTasks ?? []).filter(
    (t) => !(t.isAiSuggested === 1 && t.isApproved === 0),
  );

  // Compute stats from all tasks (unfiltered)
  const stats = useMemo(() => {
    const all = allTasks ?? [];
    return {
      total: all.length,
      todo: all.filter((t) => t.status === 'todo').length,
      inProgress: all.filter((t) => t.status === 'in_progress').length,
      completed: all.filter((t) => t.status === 'done').length,
    };
  }, [allTasks]);

  const handleCheckboxToggle = useCallback(
    (taskId: string, currentStatus: string | null) => {
      const nextStatus =
        currentStatus === 'todo' ? 'in_progress' :
        currentStatus === 'in_progress' ? 'done' : 'todo';
      updateTask.mutate({ id: taskId, status: nextStatus });
    },
    [updateTask],
  );

  return (
    <div ref={testRef} data-ai-section="test" className="flex flex-col gap-6 p-6 pe-8 w-full">
      {/* Stat Cards */}
      <div className="grid grid-cols-4 gap-4">
        <Item variant="muted">
          <ItemMedia variant="icon">
            <ClipboardCheck />
          </ItemMedia>
          <ItemContent>
            <ItemTitle>{stats.total}</ItemTitle>
            <ItemDescription>Total Tasks</ItemDescription>
          </ItemContent>
        </Item>
        <Item variant="muted">
          <ItemMedia variant="icon">
            <ListTodo />
          </ItemMedia>
          <ItemContent>
            <ItemTitle>{stats.todo}</ItemTitle>
            <ItemDescription>To Do</ItemDescription>
          </ItemContent>
        </Item>
        <Item variant="muted" className="bg-sky-50 dark:bg-sky-950/30">
          <ItemMedia variant="icon">
            <Loader2 />
          </ItemMedia>
          <ItemContent>
            <ItemTitle>{stats.inProgress}</ItemTitle>
            <ItemDescription>In Progress</ItemDescription>
          </ItemContent>
        </Item>
        <Item variant="muted" className="bg-green-50 dark:bg-green-950/30">
          <ItemMedia variant="icon">
            <CheckCircle2 />
          </ItemMedia>
          <ItemContent>
            <ItemTitle>{stats.completed}</ItemTitle>
            <ItemDescription>Completed</ItemDescription>
          </ItemContent>
        </Item>
      </div>

      {/* Search + Order By */}
      <div className="flex items-center gap-3">
        <InputGroup className="flex-1">
          <InputGroupAddon>
            <Search />
          </InputGroupAddon>
          <InputGroupInput
            placeholder="Search tasks or projects..."
            value={search}
            onChange={(e) => handleSearchChange(e.target.value)}
          />
        </InputGroup>
        <Select value={orderBy} onValueChange={(v) => setOrderBy(v as OrderBy)}>
          <SelectTrigger className="w-[180px]">
            <SelectValue placeholder="Order by" />
          </SelectTrigger>
          <SelectContent>
            {(Object.entries(ORDER_LABELS) as [OrderBy, string][]).map(([key, label]) => (
              <SelectItem key={key} value={key}>
                {label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      {/* Status Filter Tabs + New Task Button */}
      <div className="flex items-center justify-between">
        <Tabs value={statusFilter} onValueChange={(v) => setStatusFilter(v as StatusFilter)}>
          <TabsList>
            <TabsTrigger value="all">All</TabsTrigger>
            <TabsTrigger value="todo">To Do</TabsTrigger>
            <TabsTrigger value="in_progress">In Progress</TabsTrigger>
            <TabsTrigger value="done">Completed</TabsTrigger>
          </TabsList>
        </Tabs>
        <Button size="sm" onClick={() => setDialogOpen(true)}>
          <Plus className="h-4 w-4 mr-1" />
          New Task
        </Button>
      </div>

      {/* Task List */}
      <div className="flex flex-col gap-1">
        {tasksList.length === 0 ? (
          <Empty>
            <EmptyHeader>
              <EmptyMedia variant="icon">
                <ClipboardCheck />
              </EmptyMedia>
              <EmptyTitle>No tasks found</EmptyTitle>
              <EmptyDescription>
                Create a new task to get started or adjust your filters.
              </EmptyDescription>
            </EmptyHeader>
          </Empty>
        ) : (
          tasksList.map((task) => (
            <TaskRow
              key={task.id}
              task={task}
              onToggle={handleCheckboxToggle}
              onEdit={setEditTask}
              onDelete={(id) => deleteTask.mutate({ id })}
              onClick={setViewTask}
            />
          ))
        )}
      </div>

      <NewTaskDialog open={dialogOpen} onOpenChange={setDialogOpen} />
      <EditTaskDialog
        task={editTask}
        open={!!editTask}
        onOpenChange={(open: boolean) => { if (!open) setEditTask(null); }}
      />
      <TaskDetailDialog
        task={viewTask}
        open={!!viewTask}
        onOpenChange={(open) => { if (!open) setViewTask(null); }}
        onEdit={(task) => { setViewTask(null); setEditTask(task); }}
        onDelete={(id) => { deleteTask.mutate({ id }); setViewTask(null); }}
      />
    </div>
  );
}

