import { useState, useMemo, useCallback } from 'react';
import { DragDropContext, Droppable, Draggable, type DropResult } from '@hello-pangea/dnd';
import { trpc } from '@/lib/trpc';
import { useFloatingChat } from '@/context/FloatingChatContext';
import { Badge } from '@/components/ui/badge';
import { TaskRow, type TaskItem } from '@/components/tasks/TaskRow';
import { NewTaskDialog } from '@/components/tasks/NewTaskDialog';
import { EditTaskDialog } from '@/components/tasks/EditTaskDialog';
import { TaskDetailDialog } from '@/components/tasks/TaskDetailDialog';

const COLUMNS = [
  { id: 'todo', label: 'To Do' },
  { id: 'in_progress', label: 'In Progress' },
  { id: 'done', label: 'Completed' },
] as const;

type ColumnId = (typeof COLUMNS)[number]['id'];

type KanbanBoardProps = {
  projectId: string;
  newTaskOpen: boolean;
  onNewTaskOpenChange: (open: boolean) => void;
};

export function KanbanBoard({ projectId, newTaskOpen, onNewTaskOpenChange }: KanbanBoardProps) {
  const { state: floatingState } = useFloatingChat();
  const { data: tasksList } = trpc.tasks.list.useQuery({ projectId });
  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(),
  });

  // Edit / view task dialog state
  const [editTask, setEditTask] = useState<TaskItem | null>(null);
  const [viewTask, setViewTask] = useState<TaskItem | null>(null);

  // Group tasks by status (exclude unapproved AI suggestions)
  const columns = useMemo(() => {
    const tasks = (tasksList ?? []).filter(
      (t) => !(t.isAiSuggested === 1 && t.isApproved === 0),
    );
    const grouped: Record<ColumnId, TaskItem[]> = {
      todo: [],
      in_progress: [],
      done: [],
    };
    for (const task of tasks) {
      const status = (task.status ?? 'todo') as ColumnId;
      if (status in grouped) {
        grouped[status].push(task);
      } else {
        grouped.todo.push(task);
      }
    }
    return grouped;
  }, [tasksList]);

  const handleDragEnd = useCallback(
    (result: DropResult) => {
      const { destination, source, draggableId } = result;
      if (!destination) return;
      if (destination.droppableId === source.droppableId) return;

      updateTask.mutate({
        id: draggableId,
        status: destination.droppableId,
      });
    },
    [updateTask],
  );

  const handleToggle = 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 (
    <>
      <DragDropContext onDragEnd={handleDragEnd}>
        <div className="grid grid-cols-3 gap-4">
          {COLUMNS.map((col) => (
            <div key={col.id} className="flex flex-col gap-3">
              {/* Column header */}
              <div className="flex items-center gap-2">
                <span className="text-sm font-medium">{col.label}</span>
                <Badge variant="secondary" className="text-xs">
                  {columns[col.id].length}
                </Badge>
              </div>

              {/* Droppable column */}
              <Droppable droppableId={col.id}>
                {(provided, snapshot) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.droppableProps}
                    className={`flex flex-col gap-2 min-h-[120px] rounded-md transition-colors ${
                      snapshot.isDraggingOver ? 'bg-muted/50' : 'bg-muted/20'
                    }`}
                  >
                    {columns[col.id].map((task, index) => (
                      <Draggable
                        key={task.id}
                        draggableId={task.id}
                        index={index}
                      >
                        {(dragProvided) => (
                          <div
                            ref={dragProvided.innerRef}
                            {...dragProvided.draggableProps}
                            {...dragProvided.dragHandleProps}
                          >
                            <TaskRow
                              task={task}
                              onToggle={handleToggle}
                              onEdit={setEditTask}
                              onDelete={(id) => deleteTask.mutate({ id })}
                              onClick={setViewTask}
                              hideBreadcrumb
                              layoutId={
                                floatingState.morphTargetId === `task-morph-${task.id}`
                                  ? floatingState.morphTargetId
                                  : undefined
                              }
                            />
                          </div>
                        )}
                      </Draggable>
                    ))}
                    {provided.placeholder}
                  </div>
                )}
              </Droppable>
            </div>
          ))}
        </div>
      </DragDropContext>

      <NewTaskDialog
        open={newTaskOpen}
        onOpenChange={onNewTaskOpenChange}
        defaultProjectId={projectId}
      />
      <EditTaskDialog
        task={editTask}
        open={!!editTask}
        onOpenChange={(open) => { 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); }}
      />
    </>
  );
}
