'use client'

import { useState, useTransition, useEffect, useActionState } from 'react'
import { useFormStatus } from 'react-dom'
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 { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Badge } from '@/components/ui/badge'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'
import { PanelNavBar } from '@/components/shared/panel-nav-bar'
import { useSelectionStore } from '@/stores/selection-store'
import { usePlannerStore } from '@/stores/planner-store'
import { createStoryAction, updateStoryAction, deleteStoryAction, reorderStoriesAction, getStoryLogsAction } from '@/actions/stories'
import { StoryLog } from '@/components/shared/story-log'
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="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"
    >
      <p className="text-xs font-medium text-foreground line-clamp-3 min-h-[3rem]">
        {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>
  )
}

// --- Story detail slide-over ---
function StoryDetailSheet({
  story,
  productId: _productId,
  pbiId: _pbiId,
  onClose,
  isDemo,
}: {
  story: Story
  productId: string
  pbiId: string
  onClose: () => void
  isDemo: boolean
}) {
  const [confirmDelete, setConfirmDelete] = useState(false)
  const [isDeleting, startDeleteTransition] = useTransition()
  const [logs, setLogs] = useState<Awaited<ReturnType<typeof getStoryLogsAction>> | null>(null)

  useEffect(() => {
    getStoryLogsAction(story.id).then(setLogs)
  }, [story.id])

  const [state, formAction] = useActionState(
    async (_prev: unknown, fd: FormData) => {
      const result = await updateStoryAction(_prev, fd)
      if (result?.success) { toast.success('Story opgeslagen'); onClose() }
      return result
    },
    undefined
  )

  function handleDelete() {
    startDeleteTransition(async () => {
      const result = await deleteStoryAction(story.id)
      if (result && 'error' in result) toast.error(result.error ?? 'Verwijderen mislukt')
      else toast.success('Story verwijderd')
      onClose()
    })
  }

  const fieldError = (field: string) => {
    const err = state?.error
    if (!err || typeof err === 'string') return undefined
    return (err as Record<string, string[]>)[field]?.[0]
  }

  return (
    <Sheet open onOpenChange={(open) => { if (!open) onClose() }}>
      <SheetContent side="right" className="w-full sm:max-w-lg flex flex-col gap-0 p-0">
        <SheetHeader className="px-5 pt-5 pb-4 border-b border-border">
          <SheetTitle>{story.title}</SheetTitle>
          <div className="flex gap-2 mt-1">
            <Badge className={cn('text-xs border', PRIORITY_COLORS[story.priority])}>
              {PRIORITY_LABELS[story.priority]}
            </Badge>
            <Badge className={cn('text-xs border', STATUS_COLORS[story.status])}>
              {STATUS_LABELS[story.status]}
            </Badge>
          </div>
        </SheetHeader>

        <div className="flex-1 overflow-y-auto">
          {!isDemo ? (
            <form action={formAction} className="p-5 space-y-4">
              <input type="hidden" name="id" value={story.id} />
              <input type="hidden" name="priority" value={story.priority} />

              <div className="space-y-1.5">
                <label className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Titel</label>
                <Input name="title" defaultValue={story.title} required className={fieldError('title') ? 'border-error' : ''} />
                {fieldError('title') && <p className="text-xs text-error">{fieldError('title')}</p>}
              </div>

              <div className="space-y-1.5">
                <label className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Omschrijving</label>
                <Textarea name="description" rows={4} defaultValue={story.description ?? ''} placeholder="Als… wil ik… zodat…" />
              </div>

              <div className="space-y-1.5">
                <label className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Acceptatiecriteria</label>
                <Textarea name="acceptance_criteria" rows={4} defaultValue={story.acceptance_criteria ?? ''} placeholder="- Gegeven… Als… Dan…" />
              </div>

              {typeof state?.error === 'string' && (
                <p className="text-xs text-error">{state.error}</p>
              )}

              <div className="flex gap-2 pt-2">
                <SaveButton />
                <Button type="button" variant="ghost" onClick={onClose}>Annuleren</Button>
              </div>
            </form>
          ) : (
            <div className="p-5 space-y-4">
              {story.description && (
                <div>
                  <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-1">Omschrijving</p>
                  <p className="text-sm">{story.description}</p>
                </div>
              )}
              {story.acceptance_criteria && (
                <div>
                  <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-1">Acceptatiecriteria</p>
                  <p className="text-sm whitespace-pre-line">{story.acceptance_criteria}</p>
                </div>
              )}
            </div>
          )}
        </div>

        {/* Activity log */}
        <div className="px-5 py-4 border-t border-border">
          <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-3">Activiteitenlog</p>
          {logs && 'logs' in logs && logs.logs ? (
            <StoryLog logs={logs.logs.map(l => ({ ...l, status: l.status ?? null, commit_hash: l.commit_hash ?? null, commit_message: l.commit_message ?? null }))} repoUrl={logs.repoUrl} />
          ) : (
            <p className="text-xs text-muted-foreground">Laden…</p>
          )}
        </div>

        {!isDemo && (
          <div className="border-t border-border p-4">
            {confirmDelete ? (
              <div className="flex items-center gap-2">
                <span className="text-xs text-muted-foreground flex-1">Weet je het zeker? Taken worden ook verwijderd.</span>
                <Button variant="destructive" size="sm" disabled={isDeleting} onClick={handleDelete}>
                  {isDeleting ? 'Bezig…' : 'Verwijderen'}
                </Button>
                <Button variant="ghost" size="sm" onClick={() => setConfirmDelete(false)}>Annuleren</Button>
              </div>
            ) : (
              <Button
                variant="ghost"
                size="sm"
                className="text-error hover:bg-error/10"
                onClick={() => setConfirmDelete(true)}
              >
                Story verwijderen
              </Button>
            )}
          </div>
        )}
      </SheetContent>
    </Sheet>
  )
}

function SaveButton() {
  const { pending } = useFormStatus()
  return (
    <Button type="submit" disabled={pending}>
      {pending ? 'Opslaan…' : 'Opslaan'}
    </Button>
  )
}

// --- Inline create form ---
function CreateStoryForm({
  productId,
  pbiId,
  priority,
  onDone,
}: {
  productId: string
  pbiId: string
  priority: number
  onDone: () => void
}) {
  const [state, formAction] = useActionState(
    async (_prev: unknown, fd: FormData) => {
      const result = await createStoryAction(_prev, fd)
      if (result?.success) { toast.success('Story aangemaakt'); onDone() }
      return result
    },
    undefined
  )

  return (
    <form action={formAction} className="flex gap-2 items-center mt-2">
      <input type="hidden" name="pbiId" value={pbiId} />
      <input type="hidden" name="productId" value={productId} />
      <input type="hidden" name="priority" value={priority} />
      <Input name="title" autoFocus placeholder="Story titel…" className="h-7 text-sm flex-1" required />
      <CreateStorySubmitButton />
      <Button type="button" variant="ghost" size="sm" className="h-7" onClick={onDone}>×</Button>
      {typeof state?.error === 'string' && <p className="text-xs text-error">{state.error}</p>}
    </form>
  )
}

function CreateStorySubmitButton() {
  const { pending } = useFormStatus()
  return (
    <Button type="submit" size="sm" className="h-7" disabled={pending}>
      {pending ? '…' : 'Toevoegen'}
    </Button>
  )
}

// --- 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 [creatingPriority, setCreatingPriority] = useState<number | null>(null)
  const [openStory, setOpenStory] = useState<Story | 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 || creatingPriority === p
  )

  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={() => setCreatingPriority(creatingPriority ? null : 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 && creatingPriority === null ? (
          <div className="text-center mt-8 space-y-3">
            <p className="text-sm text-muted-foreground">Nog geen stories voor dit PBI.</p>
            {!isDemo && (
              <Button size="sm" variant="outline" onClick={() => setCreatingPriority(2)}>
                Maak je eerste story aan
              </Button>
            )}
          </div>
        ) : (
          <DndContext
            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 && (
                      <button
                        onClick={() => setCreatingPriority(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={() => setOpenStory(story)}
                        />
                      ))}
                    </div>
                  </SortableContext>

                  {creatingPriority === priority && selectedPbiId && (
                    <CreateStoryForm
                      productId={productId}
                      pbiId={selectedPbiId}
                      priority={priority}
                      onDone={() => setCreatingPriority(null)}
                    />
                  )}
                </div>
              ))}

              {creatingPriority !== null && !visiblePriorities.includes(creatingPriority) && selectedPbiId && (
                <div>
                  <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[creatingPriority])}>
                      {PRIORITY_LABELS[creatingPriority]}
                    </span>
                    <div className="flex-1 h-px bg-border" />
                  </div>
                  <CreateStoryForm
                    productId={productId}
                    pbiId={selectedPbiId}
                    priority={creatingPriority}
                    onDone={() => setCreatingPriority(null)}
                  />
                </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>

      {openStory && selectedPbiId && (
        <StoryDetailSheet
          story={openStory}
          productId={productId}
          pbiId={selectedPbiId}
          isDemo={isDemo}
          onClose={() => setOpenStory(null)}
        />
      )}
    </div>
  )
}
