import { useMemo, useCallback } from 'react'
import {
  DndContext,
  DragOverlay,
  PointerSensor,
  useSensor,
  useSensors,
  closestCorners,
} from '@dnd-kit/core'
import type { DragEndEvent, DragStartEvent } from '@dnd-kit/core'
import { useState } from 'react'
import { Loader2 } from 'lucide-react'
import {
  useStartTask,
  usePauseTask,
  useResumeTask,
  useCompleteTask,
} from '../api/tasks.ts'
import { WorkTaskStatus } from '../types/index.ts'
import type { WorkTask } from '../types/index.ts'
import { COLUMN_CONFIG } from '../lib/constants.ts'
import KanbanColumn from './KanbanColumn.tsx'
import TaskCard from './TaskCard.tsx'

interface KanbanBoardProps {
  tasks: WorkTask[]
  isLoading: boolean
  onTaskClick: (id: number) => void
}

export default function KanbanBoard({ tasks, isLoading, onTaskClick }: KanbanBoardProps) {
  const startTask = useStartTask()
  const pauseTask = usePauseTask()
  const resumeTask = useResumeTask()
  const completeTask = useCompleteTask()

  const [activeTask, setActiveTask] = useState<WorkTask | null>(null)

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

  // Filter to top-level tasks only and group by status
  const columns = useMemo(() => {
    const topLevel = tasks.filter((t) => t.parentTaskId === null)
    return COLUMN_CONFIG.map((col) => ({
      ...col,
      tasks: topLevel.filter((t) => t.status === col.status),
    }))
  }, [tasks])

  const handleDragStart = useCallback(
    (event: DragStartEvent) => {
      const draggedId = Number(event.active.id)
      const task = tasks.find((t) => t.id === draggedId) ?? null
      setActiveTask(task)
    },
    [tasks]
  )

  const handleDragEnd = useCallback(
    (event: DragEndEvent) => {
      setActiveTask(null)

      const { active, over } = event
      if (!over) return

      const taskId = Number(active.id)
      const task = tasks.find((t) => t.id === taskId)
      if (!task) return

      // Determine target status from the droppable column ID
      let targetStatus: string | null = null
      const overId = String(over.id)

      if (overId.startsWith('column-')) {
        targetStatus = overId.replace('column-', '')
      } else {
        // Dropped over another card - find which column it belongs to
        const overTaskId = Number(over.id)
        const overTask = tasks.find((t) => t.id === overTaskId)
        if (overTask) {
          targetStatus = overTask.status
        }
      }

      if (targetStatus === null || targetStatus === task.status) return

      // Map transitions to API calls
      switch (targetStatus) {
        case WorkTaskStatus.Active:
          // Works for both Pending->Active and Paused->Active
          if (task.status === WorkTaskStatus.Paused) {
            resumeTask.mutate({ id: taskId })
          } else {
            startTask.mutate(taskId)
          }
          break
        case WorkTaskStatus.Paused:
          if (task.status === WorkTaskStatus.Active) {
            pauseTask.mutate({ id: taskId })
          }
          break
        case WorkTaskStatus.Completed:
          completeTask.mutate(taskId)
          break
        case WorkTaskStatus.Pending:
          // Transition back to Pending is not supported
          break
      }
    },
    [tasks, startTask, pauseTask, resumeTask, completeTask]
  )

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <Loader2 className="animate-spin text-[#64748b]" size={32} />
      </div>
    )
  }

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCorners}
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
    >
      <div className="grid grid-cols-4 gap-4 h-full">
        {columns.map((col) => (
          <KanbanColumn
            key={col.status}
            status={col.status}
            label={col.label}
            color={col.color}
            tasks={col.tasks}
            onTaskClick={onTaskClick}
            onAddTask={col.status === WorkTaskStatus.Pending ? () => {} : undefined}
          />
        ))}
      </div>

      <DragOverlay>
        {activeTask ? (
          <div className="rotate-1 scale-[1.03] opacity-90">
            <TaskCard task={activeTask} onClick={() => {}} />
          </div>
        ) : null}
      </DragOverlay>
    </DndContext>
  )
}
