'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,
  rectSortingStrategy,
  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 { useBacklogStore } from '@/stores/backlog-store'
import { reorderStoriesAction } from '@/actions/stories'
import { StoryDialog, type StoryDialogState } from './story-dialog'
import { BacklogCard } from './backlog-card'
import { EmptyPanel } from './empty-panel'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import { cn } from '@/lib/utils'

type SortMode = 'priority' | 'code' | 'date'
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
  code: string | null
  title: string
  description: string | null
  acceptance_criteria: string | null
  priority: number
  status: string
  pbi_id: string
  created_at: Date
}

interface StoryPanelProps {
  productId: string
  isDemo: boolean
}

// --- Sortable story block ---
function SortableStoryBlock({
  story,
  isSelected,
  onSelect,
  onEdit,
}: {
  story: Story
  isSelected: boolean
  onSelect: () => void
  onEdit: () => 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 (
    <BacklogCard
      ref={setNodeRef}
      style={style}
      {...attributes}
      {...listeners}
      title={story.title}
      code={story.code}
      priority={story.priority}
      isDragging={isDragging}
      isSelected={isSelected}
      onClick={onSelect}
      badge={
        <Badge className={cn('text-[10px] px-1.5 py-0 border', STATUS_COLORS[story.status])}>
          {STATUS_LABELS[story.status] ?? story.status}
        </Badge>
      }
      actions={
        <button
          onClick={(e) => { e.stopPropagation(); onEdit() }}
          className="inline-flex items-center justify-center min-h-7 min-w-7 text-muted-foreground hover:text-foreground rounded transition-colors"
          aria-label="Story bewerken"
        >
          <svg className="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
            <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
          </svg>
        </button>
      }
    />
  )
}

// --- Main component ---
export function StoryPanel({ productId, isDemo }: StoryPanelProps) {
  const { selectedPbiId, selectedStoryId, selectStory } = useSelectionStore()
  const storiesByPbi = useBacklogStore((s) => s.storiesByPbi)
  const { storyOrder, initStories, reorderStories, rollbackStories } = usePlannerStore()
  const [filterStatus, setFilterStatus] = useState<string | null>(null)
  const [filterPriority, setFilterPriority] = useState<number | null>(null)
  const [sortMode, setSortMode] = useState<SortMode>(() => {
    const saved = typeof window !== 'undefined' ? localStorage.getItem('scrum4me:story_sort') : null
    return (saved === 'priority' || saved === 'code' || saved === 'date') ? saved : 'priority'
  })
  const [storyDialogState, setStoryDialogState] = useState<StoryDialogState | null>(null)
  const [activeDragId, setActiveDragId] = useState<string | null>(null)
  const [, startTransition] = useTransition()

  useEffect(() => { localStorage.setItem('scrum4me:story_sort', sortMode) }, [sortMode])

  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 base = orderedStories
    .filter(s => !filterStatus || s.status === filterStatus)
    .filter(s => !filterPriority || s.priority === filterPriority)

  const filtered = [...base].sort((a, b) => {
    if (sortMode === 'code') {
      return (a.code ?? '').localeCompare(b.code ?? '', 'nl', { numeric: true })
    }
    if (sortMode === 'date') {
      return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
    }
    return a.priority !== b.priority ? a.priority - b.priority : 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={sortMode} onValueChange={(v) => setSortMode(v as SortMode)}>
              <SelectTrigger className="h-7 w-28 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="priority">Prioriteit</SelectItem>
                <SelectItem value="code">Code</SelectItem>
                <SelectItem value="date">Datum</SelectItem>
              </SelectContent>
            </Select>
            <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 && (
              <DemoTooltip show={isDemo}>
                <Button
                  size="sm"
                  className="h-7 text-xs"
                  disabled={isDemo}
                  onClick={() => !isDemo && setStoryDialogState({ mode: 'create', pbiId: selectedPbiId, productId, defaultPriority: 2 })}
                >
                  + Story
                </Button>
              </DemoTooltip>
            )}
          </>
        }
      />

      <div className="flex-1 overflow-y-auto p-4">
        {selectedPbiId === null ? (
          <EmptyPanel message="Selecteer een PBI om de stories te bekijken." />
        ) : rawStories.length === 0 ? (
          <EmptyPanel
            message="Nog geen stories voor dit PBI."
            action={{ label: 'Maak je eerste story aan', onClick: () => setStoryDialogState({ mode: 'create', pbiId: selectedPbiId, productId, defaultPriority: 2 }), disabled: isDemo }}
          />
        ) : (
          <DndContext
            id="story-panel"
            sensors={sensors}
            collisionDetection={closestCenter}
            onDragStart={handleDragStart}
            onDragEnd={handleDragEnd}
          >
            <SortableContext items={filtered.map(s => s.id)} strategy={rectSortingStrategy}>
              <div className="grid grid-cols-3 gap-2">
                {filtered.map(story => (
                  <SortableStoryBlock
                    key={story.id}
                    story={story}
                    isSelected={selectedStoryId === story.id}
                    onSelect={() => selectStory(story.id)}
                    onEdit={() => setStoryDialogState({ mode: 'edit', story, productId })}
                  />
                ))}
              </div>
            </SortableContext>

            <DragOverlay>
              {activeDragId && storyMap[activeDragId] && (
                <BacklogCard
                  title={storyMap[activeDragId].title}
                  priority={storyMap[activeDragId].priority}
                  className="border-primary shadow-xl opacity-90"
                />
              )}
            </DragOverlay>
          </DndContext>
        )}
      </div>

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