'use client'

import { useState, useTransition, useEffect } from 'react'
import { useRouter, usePathname } from 'next/navigation'
import {
  DndContext, DragEndEvent, DragOverlay,
  KeyboardSensor, PointerSensor, useSensor, useSensors, closestCenter,
} from '@dnd-kit/core'
import {
  SortableContext, useSortable, verticalListSortingStrategy, arrayMove,
  sortableKeyboardCoordinates,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { Pencil } from 'lucide-react'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { CodeBadge } from '@/components/shared/code-badge'
import { PanelNavBar } from '@/components/shared/panel-nav-bar'
import { PRIORITY_BORDER } from '@/components/backlog/backlog-card'
import { useSprintStore } from '@/stores/sprint-store'
import { updateTaskStatusAction, reorderTasksAction } from '@/actions/tasks'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import { cn } from '@/lib/utils'

const STATUS_CYCLE: Record<string, 'TO_DO' | 'IN_PROGRESS' | 'DONE'> = {
  TO_DO: 'IN_PROGRESS',
  IN_PROGRESS: 'DONE',
  DONE: 'TO_DO',
}
const STATUS_COLORS: Record<string, string> = {
  TO_DO: 'bg-status-todo/15 text-status-todo border-status-todo/30',
  IN_PROGRESS: 'bg-status-in-progress/15 text-status-in-progress border-status-in-progress/30',
  DONE: 'bg-status-done/15 text-status-done border-status-done/30',
}
const STATUS_LABELS: Record<string, string> = { TO_DO: 'To Do', IN_PROGRESS: 'Bezig', DONE: 'Klaar' }


export interface Task {
  id: string
  code: string
  title: string
  description: string | null
  priority: number
  status: string
  story_id: string
  sprint_id: string | null
}

interface TaskListProps {
  storyId: string
  sprintId: string
  productId: string
  tasks: Task[]
  isDemo: boolean
}

function SortableTaskRow({
  task, code, isDemo, onStatusToggle, onEdit,
}: {
  task: Task
  code: string | null
  isDemo: boolean
  onStatusToggle: () => void
  onEdit: () => void
}) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: task.id })
  const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.4 : 1 }

  return (
    <div ref={setNodeRef} style={style} className="group px-2 py-1">
      <div
        className={cn(
          'flex items-start gap-2 rounded border border-border px-3 py-2 transition-colors bg-surface-container hover:bg-surface-container-high cursor-pointer',
          PRIORITY_BORDER[task.priority],
        )}
        onClick={() => onEdit()}
        role="button"
        tabIndex={0}
        aria-label={`Bewerk taak: ${task.title}`}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault()
            onEdit()
          }
        }}
      >
        {!isDemo && (
          <span
            {...attributes}
            {...listeners}
            onClick={(e) => e.stopPropagation()}
            className="text-muted-foreground cursor-grab active:cursor-grabbing shrink-0 text-sm select-none mt-0.5"
            aria-hidden="true"
          >
            ⠿
          </span>
        )}
        <div className="flex-1 min-w-0">
          <div className="flex items-start justify-between gap-2">
            <p className={cn(
              'text-sm leading-snug line-clamp-2 flex-1',
              task.status === 'DONE' && 'line-through text-muted-foreground',
            )}>
              {task.title}
            </p>
            {code && <CodeBadge code={code} className="shrink-0 mt-0.5" />}
          </div>
          <div className="mt-1.5">
            <button
              onClick={(e) => { e.stopPropagation(); onStatusToggle() }}
              disabled={isDemo}
              aria-label={`Status: ${STATUS_LABELS[task.status]}`}
            >
              <Badge className={cn(
                'text-[10px] px-1.5 py-0 border cursor-pointer hover:opacity-80 transition-opacity',
                STATUS_COLORS[task.status],
              )}>
                {STATUS_LABELS[task.status]}
              </Badge>
            </button>
          </div>
        </div>
        <DemoTooltip show={isDemo}>
          <button
            onClick={(e) => { e.stopPropagation(); if (!isDemo) onEdit() }}
            className="opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-foreground p-0.5 rounded shrink-0 mt-0.5 disabled:opacity-40 disabled:cursor-not-allowed"
            aria-label="Bewerk taak"
            disabled={isDemo}
          >
            <Pencil size={14} />
          </button>
        </DemoTooltip>
      </div>
    </div>
  )
}

export function TaskList({ storyId, sprintId: _sprintId, productId: _productId, tasks, isDemo }: TaskListProps) {
  const { taskOrder, initTasks, reorderTasks, rollbackTasks } = useSprintStore()
  const [activeDragId, setActiveDragId] = useState<string | null>(null)
  const [, startTransition] = useTransition()
  const router = useRouter()
  const pathname = usePathname()

  const idKey = tasks.map(t => t.id).join(',')
  useEffect(() => {
    initTasks(storyId, idKey ? idKey.split(',') : [])
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [storyId, idKey])

  const taskMap = Object.fromEntries(tasks.map(t => [t.id, t]))
  const order = taskOrder[storyId] ?? tasks.map(t => t.id)
  const orderedTasks = order.map(id => taskMap[id]).filter(Boolean)

  const doneCount = orderedTasks.filter(t => t.status === 'DONE').length

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
  )

  function handleDragEnd(event: DragEndEvent) {
    const { active, over } = event
    if (!over || active.id === over.id) return
    const prevOrder = [...order]
    const newOrder = arrayMove([...order], order.indexOf(active.id as string), order.indexOf(over.id as string))
    reorderTasks(storyId, newOrder)
    setActiveDragId(null)
    startTransition(async () => {
      const result = await reorderTasksAction(storyId, newOrder)
      if (!result.success) { rollbackTasks(storyId, prevOrder); toast.error('Volgorde opslaan mislukt') }
    })
  }

  function handleStatusToggle(task: Task) {
    startTransition(async () => {
      await updateTaskStatusAction(task.id, STATUS_CYCLE[task.status] ?? 'TO_DO')
    })
  }

  function openCreateDialog() {
    router.push(`${pathname}?newTask=1&storyId=${storyId}`)
  }

  function openEditDialog(taskId: string) {
    router.push(`${pathname}?editTask=${taskId}`)
  }

  return (
    <div className="flex flex-col h-full">
      <PanelNavBar
        title="Taken"
        actions={
          <>
            <span className="text-xs text-muted-foreground">{doneCount}/{orderedTasks.length} klaar</span>
            <DemoTooltip show={isDemo}>
              <Button
                size="sm"
                className="h-7 text-xs"
                disabled={isDemo}
                onClick={() => !isDemo && openCreateDialog()}
              >
                + Taak
              </Button>
            </DemoTooltip>
          </>
        }
      />

      <div className="flex-1 overflow-y-auto">
        {orderedTasks.length === 0 ? (
          <div className="text-center mt-8 space-y-3">
            <p className="text-sm text-muted-foreground">Geen taken voor deze story.</p>
            <DemoTooltip show={isDemo}>
              <Button
                size="sm"
                variant="outline"
                disabled={isDemo}
                onClick={() => !isDemo && openCreateDialog()}
              >
                Maak eerste taak aan
              </Button>
            </DemoTooltip>
          </div>
        ) : (
          <DndContext
            id="task-list"
            sensors={sensors}
            collisionDetection={closestCenter}
            onDragStart={e => setActiveDragId(e.active.id as string)}
            onDragEnd={handleDragEnd}
          >
            <SortableContext items={orderedTasks.map(t => t.id)} strategy={verticalListSortingStrategy}>
              {orderedTasks.map((task) => (
                <SortableTaskRow
                  key={task.id}
                  task={task}
                  code={task.code}
                  isDemo={isDemo}
                  onStatusToggle={() => handleStatusToggle(task)}
                  onEdit={() => openEditDialog(task.id)}
                />
              ))}
            </SortableContext>
            <DragOverlay>
              {activeDragId && taskMap[activeDragId] && (
                <div className={cn(
                  'rounded border border-primary px-3 py-2 bg-surface-container shadow-lg opacity-90 text-sm',
                  PRIORITY_BORDER[taskMap[activeDragId].priority],
                )}>
                  {taskMap[activeDragId].title}
                </div>
              )}
            </DragOverlay>
          </DndContext>
        )}
      </div>
    </div>
  )
}
