'use client'

import { useState, useTransition, useEffect } from 'react'
import {
  DndContext,
  DragEndEvent,
  DragOverlay,
  DragStartEvent,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  closestCenter,
} from '@dnd-kit/core'
import {
  SortableContext,
  useSortable,
  horizontalListSortingStrategy,
  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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { PanelNavBar } from '@/components/shared/panel-nav-bar'
import { useSelectionStore } from '@/stores/selection-store'
import { usePlannerStore } from '@/stores/planner-store'
import { reorderStoriesAction } from '@/actions/stories'
import { StoryDialog, type StoryDialogState } from './story-dialog'
import { cn } from '@/lib/utils'

const PRIORITY_LABELS: Record<number, string> = { 1: 'Kritiek', 2: 'Hoog', 3: 'Gemiddeld', 4: 'Laag' }
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 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',
}

export interface Story {
  id: string
  title: string
  description: string | null
  acceptance_criteria: string | null
  priority: number
  status: string
  pbi_id: string
}

interface StoryPanelProps {
  productId: string
  storiesByPbi: Record<string, Story[]>
  isDemo: boolean
}

// --- Sortable story block ---
function SortableStoryBlock({
  story,
  onClick,
}: {
  story: Story
  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}
      {...attributes}
      {...listeners}
      onClick={onClick}
      title={story.title}
      className="relative w-28 shrink-0 bg-surface-container-low border border-border rounded-lg p-2 cursor-pointer hover:border-primary transition-colors space-y-1.5 select-none"
    >
      <button
        onClick={(e) => { e.stopPropagation(); onClick() }}
        onPointerDown={(e) => e.stopPropagation()}
        className="absolute top-1.5 right-2 border border-border rounded px-1 py-0.5 text-xs text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors leading-none"
        aria-label="Bewerk story"
      >
        ✎
      </button>
      <p className="text-xs font-medium text-foreground line-clamp-3 min-h-[3rem] pr-4">
        {story.title}
      </p>
      <div className="flex flex-col gap-1">
        <Badge className={cn('text-[10px] px-1.5 py-0 border', PRIORITY_COLORS[story.priority])}>
          {PRIORITY_LABELS[story.priority]}
        </Badge>
        <Badge className={cn('text-[10px] px-1.5 py-0 border', STATUS_COLORS[story.status])}>
          {STATUS_LABELS[story.status] ?? story.status}
        </Badge>
      </div>
    </div>
  )
}

// --- Main component ---
export function StoryPanel({ productId, storiesByPbi, isDemo }: StoryPanelProps) {
  const { selectedPbiId } = useSelectionStore()
  const { storyOrder, initStories, reorderStories, rollbackStories } = usePlannerStore()
  const [filterStatus, setFilterStatus] = useState<string | null>(null)
  const [filterPriority, setFilterPriority] = useState<number | null>(null)
  const [storyDialogState, setStoryDialogState] = useState<StoryDialogState | null>(null)
  const [activeDragId, setActiveDragId] = useState<string | null>(null)
  const [, startTransition] = useTransition()

  const rawStories = selectedPbiId ? (storiesByPbi[selectedPbiId] ?? []) : []

  // Sync into store — use stable string dep to avoid infinite loop
  const storyIdKey = rawStories.map(s => s.id).join(',')
  useEffect(() => {
    if (selectedPbiId) {
      initStories(selectedPbiId, storyIdKey ? storyIdKey.split(',') : [])
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedPbiId, storyIdKey])

  const storyMap = Object.fromEntries(rawStories.map(s => [s.id, s]))
  const order = (selectedPbiId ? storyOrder[selectedPbiId] : null) ?? rawStories.map(s => s.id)
  const orderedStories = order.map(id => storyMap[id]).filter(Boolean)

  const filtered = orderedStories
    .filter(s => !filterStatus || s.status === filterStatus)
    .filter(s => !filterPriority || s.priority === filterPriority)

  const grouped = [1, 2, 3, 4].reduce<Record<number, Story[]>>((acc, p) => {
    acc[p] = filtered.filter(s => s.priority === p)
    return acc
  }, {} as Record<number, Story[]>)

  const visiblePriorities = [1, 2, 3, 4].filter(p => grouped[p].length > 0)

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

  function handleDragStart(event: DragStartEvent) {
    setActiveDragId(event.active.id as string)
  }

  function handleDragEnd(event: DragEndEvent) {
    setActiveDragId(null)
    const { active, over } = event
    if (!over || active.id === over.id || !selectedPbiId) return

    const activeStory = storyMap[active.id as string]
    const overStory = storyMap[over.id as string]
    if (!activeStory || !overStory) return

    const prevOrder = [...order]
    const oldIndex = order.indexOf(active.id as string)
    const newIndex = order.indexOf(over.id as string)
    const newOrder = arrayMove([...order], oldIndex, newIndex)

    reorderStories(selectedPbiId, newOrder)

    const priorityChanged = activeStory.priority !== overStory.priority

    startTransition(async () => {
      const result = await reorderStoriesAction(
        selectedPbiId,
        productId,
        newOrder,
        priorityChanged ? overStory.priority : undefined
      )
      if (!result.success) {
        rollbackStories(selectedPbiId, prevOrder)
        toast.error('Volgorde opslaan mislukt')
      }
    })
  }

  const hasActiveFilters = filterStatus !== null || filterPriority !== null

  return (
    <div className="flex flex-col h-full">
      <PanelNavBar
        title="Stories"
        actions={
          <>
            {hasActiveFilters && (
              <button onClick={() => { setFilterStatus(null); setFilterPriority(null) }} className="text-xs text-primary hover:underline">
                Filter wissen ×
              </button>
            )}
            <Select
              value={filterStatus ?? 'all'}
              onValueChange={(v) => setFilterStatus(!v || v === 'all' ? null : v)}
            >
              <SelectTrigger className="h-7 w-24 text-xs">
                <SelectValue placeholder="Status" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">Alle</SelectItem>
                <SelectItem value="OPEN">Open</SelectItem>
                <SelectItem value="IN_SPRINT">In Sprint</SelectItem>
                <SelectItem value="DONE">Klaar</SelectItem>
              </SelectContent>
            </Select>
            {selectedPbiId && !isDemo && (
              <Button
                size="sm"
                className="h-7 text-xs"
                onClick={() => setStoryDialogState({ mode: 'create', pbiId: selectedPbiId, productId, defaultPriority: 2 })}
              >
                + Story
              </Button>
            )}
          </>
        }
      />

      <div className="flex-1 overflow-y-auto p-4">
        {selectedPbiId === null ? (
          <p className="text-sm text-muted-foreground text-center mt-8">
            Selecteer een PBI om de stories te bekijken.
          </p>
        ) : rawStories.length === 0 ? (
          <div className="text-center mt-8 space-y-3">
            <p className="text-sm text-muted-foreground">Nog geen stories voor dit PBI.</p>
            {!isDemo && selectedPbiId && (
              <Button size="sm" variant="outline" onClick={() => setStoryDialogState({ mode: 'create', pbiId: selectedPbiId, productId, defaultPriority: 2 })}>
                Maak je eerste story aan
              </Button>
            )}
          </div>
        ) : (
          <DndContext
            id="story-panel"
            sensors={sensors}
            collisionDetection={closestCenter}
            onDragStart={handleDragStart}
            onDragEnd={handleDragEnd}
          >
            <div className="space-y-4">
              {visiblePriorities.map(priority => (
                <div key={priority}>
                  <div className="flex items-center gap-2 mb-2">
                    <span className={cn('text-xs font-semibold px-2 py-0.5 rounded-full border', PRIORITY_COLORS[priority])}>
                      {PRIORITY_LABELS[priority]}
                    </span>
                    <div className="flex-1 h-px bg-border" />
                    {!isDemo && selectedPbiId && (
                      <button
                        onClick={() => setStoryDialogState({ mode: 'create', pbiId: selectedPbiId, productId, defaultPriority: priority })}
                        className="text-xs text-muted-foreground hover:text-foreground"
                      >
                        +
                      </button>
                    )}
                  </div>

                  <SortableContext
                    items={grouped[priority].map(s => s.id)}
                    strategy={horizontalListSortingStrategy}
                  >
                    <div className="flex flex-wrap gap-2">
                      {grouped[priority].map(story => (
                        <SortableStoryBlock
                          key={story.id}
                          story={story}
                          onClick={() => setStoryDialogState({ mode: 'edit', story, productId })}
                        />
                      ))}
                    </div>
                  </SortableContext>

                </div>
              ))}
            </div>

            <DragOverlay>
              {activeDragId && storyMap[activeDragId] && (
                <div className="w-28 bg-surface-container-low border border-primary rounded-lg p-2 shadow-lg opacity-90">
                  <p className="text-xs font-medium line-clamp-3">{storyMap[activeDragId].title}</p>
                </div>
              )}
            </DragOverlay>
          </DndContext>
        )}
      </div>

      <StoryDialog
        state={storyDialogState}
        onClose={() => setStoryDialogState(null)}
        isDemo={isDemo}
      />
    </div>
  )
}
