"use client";

import { useState, useCallback, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useQueryClient } from "@tanstack/react-query";
import {
  DndContext,
  PointerSensor,
  pointerWithin,
  useSensor,
  useSensors,
  type DragEndEvent,
} from "@dnd-kit/core";
import { useMarkInProgress } from "@/lib/hooks/use-tasks";
import { useDataProvider, useQueryKeyPrefix } from "@/lib/demo/data-provider-context";
import { KanbanColumn } from "./kanban-column";
import type { KanbanResponse, KanbanColumn as KanbanColumnType } from "@/lib/api/tasks";

interface KanbanBoardProps {
  data: KanbanResponse;
}

export function KanbanBoard({ data }: KanbanBoardProps) {
  const router = useRouter();
  const queryClient = useQueryClient();
  const { basePath } = useDataProvider();
  const qk = useQueryKeyPrefix();
  const markInProgress = useMarkInProgress();

  // Local columns state for instant optimistic updates
  const [columns, setColumns] = useState<KanbanColumnType[]>(data.columns);

  // Sync with prop changes (e.g. after server refetch)
  useEffect(() => {
    setColumns(data.columns);
  }, [data.columns]);

  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: { distance: 8 },
    })
  );

  const moveTask = useCallback(
    (taskId: number, sourceColName: string, targetColName: string) => {
      const sourceCol = columns.find((c) => c.name === sourceColName);
      const task = sourceCol?.tasks.find((t) => t.id === taskId);
      if (!task) return;

      setColumns((prev) =>
        prev.map((col) => {
          if (col.name === sourceColName) {
            const tasks = col.tasks.filter((t) => t.id !== taskId);
            return { ...col, tasks, count: tasks.length };
          }
          if (col.name === targetColName) {
            const tasks = [...col.tasks, task];
            return { ...col, tasks, count: tasks.length };
          }
          return col;
        })
      );
    },
    [columns]
  );

  const handleDragEnd = useCallback(
    (event: DragEndEvent) => {
      const { active, over } = event;
      if (!over) return;

      const taskId = active.id as number;
      const targetColumn = over.id as string;

      // Find source column
      const sourceCol = columns.find((col) =>
        col.tasks.some((t) => t.id === taskId)
      );
      if (!sourceCol || sourceCol.name === targetColumn) return;

      if (targetColumn === "completed_tasks") {
        router.push(`${basePath}/tasks/${taskId}/complete`);
        return;
      }

      if (targetColumn === "in_progress_tasks") {
        // Optimistic move + API call
        moveTask(taskId, sourceCol.name, targetColumn);
        markInProgress.mutate(taskId, {
          onError: () => setColumns(data.columns),
          onSettled: () => {
            queryClient.invalidateQueries({ queryKey: qk("tasks") });
          },
        });
        return;
      }

      // For any other column, just do an optimistic visual move
      // (no API endpoint for moving to overdue/due_soon/upcoming — those are computed server-side)
      moveTask(taskId, sourceCol.name, targetColumn);
      // Refetch to get correct server state
      queryClient.invalidateQueries({ queryKey: qk("tasks") });
    },
    [columns, data.columns, moveTask, markInProgress, queryClient, qk, router, basePath]
  );

  return (
    <DndContext sensors={sensors} collisionDetection={pointerWithin} onDragEnd={handleDragEnd}>
      <div className="flex gap-4 overflow-x-auto pb-4 snap-x snap-mandatory sm:snap-none -mx-4 px-4 sm:mx-0 sm:px-0">
        {columns.map((column) => (
          <KanbanColumn key={column.name} column={column} />
        ))}
      </div>
    </DndContext>
  );
}
