'use client'

import { useState, useTransition, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import {
  DndContext, DragEndEvent,
  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 { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { PanelNavBar } from '@/components/shared/panel-nav-bar'
import { useSprintStore } from '@/stores/sprint-store'
import {
  addStoryToSprintAction,
  removeStoryFromSprintAction,
  reorderSprintStoriesAction,
} from '@/actions/sprints'
import { cn } from '@/lib/utils'

const STATUS_COLORS: Record<string, string> = {
  OPEN: 'bg-status-todo/15 text-status-todo border-status-todo/30',
  IN_SPRINT: '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> = { OPEN: 'Open', IN_SPRINT: 'In Sprint', DONE: 'Klaar' }

const PRIORITY_COLORS: Record<number, string> = {
  1: 'bg-priority-critical/15 text-priority-critical border-priority-critical/30',
  2: 'bg-priority-high/15 text-priority-high border-priority-high/30',
  3: 'bg-priority-medium/15 text-priority-medium border-priority-medium/30',
  4: 'bg-priority-low/15 text-priority-low border-priority-low/30',
}
const PRIORITY_LABELS: Record<number, string> = { 1: 'Kritiek', 2: 'Hoog', 3: 'Gemiddeld', 4: 'Laag' }

export interface SprintStory {
  id: string
  title: string
  priority: number
  status: string
  taskCount: number
  doneCount: number
}

export interface PbiWithStories {
  id: string
  title: string
  stories: SprintStory[]
}

// --- Left panel: Sprint Backlog ---
function SortableSprintRow({
  story, isDemo, onRemove, onClick,
}: { story: SprintStory; isDemo: boolean; onRemove: () => void; onClick: () => void }) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: story.id })
  const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.4 : 1 }

  return (
    <div
      ref={setNodeRef}
      style={style}
      onClick={onClick}
      className="group flex items-center gap-3 px-4 py-2.5 border-b border-border hover:bg-surface-container transition-colors cursor-pointer"
    >
      {!isDemo && (
        <span {...attributes} {...listeners} onClick={e => e.stopPropagation()}
          aria-label="Versleep om te sorteren"
          className="text-muted-foreground cursor-grab active:cursor-grabbing shrink-0 select-none text-sm">
          ⠿
        </span>
      )}
      <div className="flex-1 min-w-0">
        <p className="text-sm truncate">{story.title}</p>
        <div className="flex items-center gap-1.5 mt-0.5">
          <Badge className={cn('text-[10px] px-1.5 py-0 border', PRIORITY_COLORS[story.priority])}>
            {PRIORITY_LABELS[story.priority]}
          </Badge>
          <span className="text-xs text-muted-foreground">{story.doneCount}/{story.taskCount} klaar</span>
        </div>
      </div>
      {!isDemo && (
        <button onClick={e => { e.stopPropagation(); onRemove() }}
          className="opacity-0 group-hover:opacity-100 text-xs text-muted-foreground hover:text-error shrink-0">
          Verwijderen
        </button>
      )}
    </div>
  )
}

interface SprintBacklogLeftProps {
  sprintId: string
  stories: SprintStory[]
  isDemo: boolean
  onSelectStory: (id: string) => void
  selectedStoryId: string | null
}

export function SprintBacklogLeft({ sprintId, stories, isDemo, onSelectStory }: SprintBacklogLeftProps) {
  const { sprintStoryOrder, initSprint, reorderSprintStories, rollbackSprint, removeStoryFromSprint } = useSprintStore()
  const [, startTransition] = useTransition()

  const idKey = stories.map(s => s.id).join(',')
  useEffect(() => {
    initSprint(sprintId, idKey ? idKey.split(',') : [])
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sprintId, idKey])

  const storyMap = Object.fromEntries(stories.map(s => [s.id, s]))
  const order = sprintStoryOrder[sprintId] ?? stories.map(s => s.id)
  const orderedStories = order.map(id => storyMap[id]).filter(Boolean)

  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))
    reorderSprintStories(sprintId, newOrder)
    startTransition(async () => {
      const result = await reorderSprintStoriesAction(sprintId, newOrder)
      if (!result.success) { rollbackSprint(sprintId, prevOrder); toast.error('Volgorde opslaan mislukt') }
    })
  }

  function handleRemove(storyId: string) {
    removeStoryFromSprint(sprintId, storyId)
    startTransition(async () => {
      const result = await removeStoryFromSprintAction(storyId)
      if (!result.success) toast.error('Verwijderen mislukt')
    })
  }

  return (
    <div className="flex flex-col h-full">
      <PanelNavBar title="Sprint Backlog" />
      <div className="flex-1 overflow-y-auto">
        {orderedStories.length === 0 ? (
          <p className="text-sm text-muted-foreground text-center mt-8 px-4">
            Geen stories in de Sprint. Sleep stories vanuit het rechterpaneel.
          </p>
        ) : (
          <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
            <SortableContext items={orderedStories.map(s => s.id)} strategy={verticalListSortingStrategy}>
              {orderedStories.map(story => (
                <SortableSprintRow
                  key={story.id}
                  story={story}
                  isDemo={isDemo}
                  onRemove={() => handleRemove(story.id)}
                  onClick={() => onSelectStory(story.id)}
                />
              ))}
            </SortableContext>
          </DndContext>
        )}
      </div>
    </div>
  )
}

// --- Right panel: Product Backlog stories grouped by PBI (droppable source) ---
interface SprintBacklogRightProps {
  sprintId: string
  pbisWithStories: PbiWithStories[]
  sprintStoryIds: Set<string>
  isDemo: boolean
  onStoryAdded: (storyId: string) => void
}

export function SprintBacklogRight({ sprintId, pbisWithStories, sprintStoryIds, isDemo, onStoryAdded }: SprintBacklogRightProps) {
  const [collapsed, setCollapsed] = useState<Set<string>>(new Set())
  const [, startTransition] = useTransition()
  const { addStoryToSprint } = useSprintStore()
  const router = useRouter()

  function toggle(pbiId: string) {
    setCollapsed(prev => {
      const next = new Set(prev)
      if (next.has(pbiId)) { next.delete(pbiId) } else { next.add(pbiId) }
      return next
    })
  }

  function handleAdd(storyId: string) {
    addStoryToSprint(sprintId, storyId)
    onStoryAdded(storyId)
    startTransition(async () => {
      const result = await addStoryToSprintAction(sprintId, storyId)
      if (!result.success) {
        toast.error(result.error ?? 'Toevoegen mislukt')
        router.refresh()
      }
    })
  }

  return (
    <div className="flex flex-col h-full">
      <PanelNavBar title="Product Backlog" />
      <div className="flex-1 overflow-y-auto py-2">
        {pbisWithStories.map(pbi => (
          <div key={pbi.id}>
            <button
              onClick={() => toggle(pbi.id)}
              className="w-full flex items-center gap-2 px-4 py-1.5 hover:bg-surface-container transition-colors text-left"
            >
              <span className="text-xs">{collapsed.has(pbi.id) ? '▶' : '▼'}</span>
              <span className="text-sm font-medium truncate flex-1">{pbi.title}</span>
              <span className="text-xs text-muted-foreground">{pbi.stories.length}</span>
            </button>

            {!collapsed.has(pbi.id) && pbi.stories.map(story => {
              const inSprint = sprintStoryIds.has(story.id)
              return (
                <div
                  key={story.id}
                  className={cn(
                    'flex items-center gap-3 px-6 py-2 border-b border-border/50 transition-colors',
                    inSprint ? 'opacity-50' : 'hover:bg-surface-container'
                  )}
                >
                  <div className="flex-1 min-w-0">
                    <p className="text-sm truncate">{story.title}</p>
                    <Badge className={cn('text-[10px] px-1.5 py-0 border mt-0.5', STATUS_COLORS[story.status])}>
                      {STATUS_LABELS[story.status]}
                    </Badge>
                  </div>
                  {!inSprint && !isDemo && (
                    <Button size="sm" variant="outline" className="h-6 text-xs shrink-0" onClick={() => handleAdd(story.id)}>
                      + Sprint
                    </Button>
                  )}
                  {inSprint && <span className="text-xs text-muted-foreground shrink-0">In Sprint</span>}
                </div>
              )
            })}
          </div>
        ))}
      </div>
    </div>
  )
}
