'use client'

import { useMemo, useState } from 'react'
import {
  DndContext,
  DragOverlay,
  PointerSensor,
  useSensor,
  useSensors,
  useDraggable,
  useDroppable,
  type DragEndEvent,
  type DragStartEvent,
} from '@dnd-kit/core'
import type { Note } from '@/lib/types'
import type { NotebookSchemaPayload, NotePropertyValues } from '@/lib/structured-views/types'
import { getNoteDisplayTitle } from '@/lib/note-preview'
import { useLanguage } from '@/lib/i18n'
import { Plus } from 'lucide-react'
import { cn } from '@/lib/utils'

type NotesKanbanViewProps = {
  notes: Note[]
  schema: NotebookSchemaPayload
  noteValues: Record<string, NotePropertyValues>
  onOpen: (note: Note) => void
  onPropertyChange: (noteId: string, propertyId: string, value: unknown) => void
  onCreateNote: (prefill: Record<string, unknown>) => void
  onSetGroupProperty: (propertyId: string) => void
  onQuickAddKanbanStatus?: () => void
}

function DraggableCard({ note, onOpen, dragDisabled }: { note: Note; onOpen: (note: Note) => void; dragDisabled?: boolean }) {
  const { t } = useLanguage()
  const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable({ id: note.id, disabled: dragDisabled })
  const style = transform
    ? { transform: `translate3d(${transform.x}px, ${transform.y}px, 0)` }
    : undefined

  return (
    <div
      ref={setNodeRef}
      style={style}
      {...(dragDisabled ? {} : listeners)}
      {...(dragDisabled ? {} : attributes)}
      className={cn(
        'rounded-xl border border-border/50 bg-card p-3 shadow-sm',
        !dragDisabled && 'cursor-grab active:cursor-grabbing touch-none',
        isDragging && 'opacity-40',
      )}
    >
      <button
        type="button"
        onClick={() => onOpen(note)}
        className="font-memento-serif text-[13px] font-medium text-left w-full hover:text-brand-accent transition-colors pointer-events-auto"
      >
        {getNoteDisplayTitle(note, t('notes.untitled'))}
      </button>
    </div>
  )
}

function DroppableColumn({
  id,
  children,
  className,
}: {
  id: string
  children: React.ReactNode
  className?: string
}) {
  const { setNodeRef, isOver } = useDroppable({ id })
  return (
    <div
      ref={setNodeRef}
      className={cn(className, isOver && 'ring-2 ring-brand-accent/30 ring-inset')}
    >
      {children}
    </div>
  )
}

export function NotesKanbanView({
  notes,
  schema,
  noteValues,
  onOpen,
  onPropertyChange,
  onCreateNote,
  onSetGroupProperty,
  onQuickAddKanbanStatus,
}: NotesKanbanViewProps) {
  const { t } = useLanguage()
  const [activeId, setActiveId] = useState<string | null>(null)

  const selectProps = schema.properties.filter((p) => p.type === 'select')
  const groupPropId =
    schema.viewSettings.kanbanGroupPropertyId &&
    selectProps.some((p) => p.id === schema.viewSettings.kanbanGroupPropertyId)
      ? schema.viewSettings.kanbanGroupPropertyId
      : selectProps[0]?.id ?? null

  const groupProp = selectProps.find((p) => p.id === groupPropId) ?? null

  const columns = useMemo(() => {
    if (!groupProp) {
      return [{ id: 'col:__none', label: t('structuredViews.kanbanAllNotes'), value: null as string | null }]
    }
    const cols = groupProp.options.map((opt) => ({ id: `col:${opt}`, label: opt, value: opt }))
    return [...cols, { id: 'col:__none', label: t('structuredViews.kanbanUnassigned'), value: null }]
  }, [groupProp, t])

  const notesByColumn = useMemo(() => {
    const map = new Map<string, Note[]>()
    for (const col of columns) map.set(col.id, [])
    for (const note of notes) {
      if (!groupProp) {
        map.get('col:__none')?.push(note)
        continue
      }
      const raw = noteValues[note.id]?.[groupProp.id]
      const val = typeof raw === 'string' ? raw : null
      const colId = val && groupProp.options.includes(val) ? `col:${val}` : 'col:__none'
      map.get(colId)?.push(note)
    }
    return map
  }, [notes, noteValues, groupProp, columns])

  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } }))

  const handleDragStart = (e: DragStartEvent) => setActiveId(String(e.active.id))
  const handleDragEnd = (e: DragEndEvent) => {
    setActiveId(null)
    const noteId = String(e.active.id)
    const overId = e.over?.id ? String(e.over.id) : null
    if (!overId || !groupProp || !overId.startsWith('col:')) return
    const value = overId === 'col:__none' ? null : overId.slice(4)
    onPropertyChange(noteId, groupProp.id, value)
  }

  const activeNote = activeId ? notes.find((n) => n.id === activeId) : null

  return (
    <div className="space-y-4">
      {!groupProp && (
        <div className="rounded-xl border border-border/40 bg-foreground/[0.02] px-4 py-3 flex flex-col sm:flex-row sm:items-center gap-3">
          <p className="text-[13px] text-muted-foreground flex-1">{t('structuredViews.kanbanSingleColumnHint')}</p>
          {onQuickAddKanbanStatus && (
            <button
              type="button"
              onClick={onQuickAddKanbanStatus}
              className="shrink-0 px-4 py-2 rounded-full bg-foreground text-background text-[11px] font-bold uppercase tracking-wider"
            >
              {t('structuredViews.kanbanAddStatusColumns')}
            </button>
          )}
        </div>
      )}

      {groupProp && selectProps.length > 1 && (
        <div className="flex flex-wrap items-center gap-2 text-[11px]">
          <span className="text-muted-foreground uppercase tracking-widest font-bold">
            {t('structuredViews.kanbanGroupBy')}
          </span>
          <select
            value={groupProp.id}
            onChange={(e) => onSetGroupProperty(e.target.value)}
            className="rounded-lg border border-border bg-background px-2 py-1"
          >
            {selectProps.map((p) => (
              <option key={p.id} value={p.id}>{p.name}</option>
            ))}
          </select>
        </div>
      )}

      <DndContext sensors={sensors} onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
        <div className="flex gap-4 overflow-x-auto pb-4 min-h-[420px]">
          {columns.map((col) => {
            const colNotes = notesByColumn.get(col.id) ?? []
            return (
              <div
                key={col.id}
                className="flex-shrink-0 w-[260px] rounded-2xl border border-border/40 bg-foreground/[0.02] flex flex-col"
              >
                <div className="px-3 py-3 border-b border-border/30 flex items-center justify-between">
                  <span className="text-[10px] font-black uppercase tracking-widest text-muted-foreground">
                    {col.label}
                  </span>
                  <span className="text-[10px] text-muted-foreground">{colNotes.length}</span>
                </div>
                <DroppableColumn id={col.id} className="flex-1 p-2 space-y-2 min-h-[120px]">
                  {colNotes.map((note) => (
                    <DraggableCard key={note.id} note={note} onOpen={onOpen} dragDisabled={!groupProp} />
                  ))}
                </DroppableColumn>
                {groupProp && (
                  <button
                    type="button"
                    onClick={() => onCreateNote({ [groupProp.id]: col.value })}
                    className="m-2 flex items-center justify-center gap-1 py-2 rounded-lg border border-dashed border-border text-[11px] text-muted-foreground hover:border-foreground/30 hover:text-foreground transition-colors"
                  >
                    <Plus size={14} />
                    {t('structuredViews.newNoteInColumn')}
                  </button>
                )}
              </div>
            )
          })}
        </div>
        <DragOverlay>
          {activeNote ? (
            <div className="rounded-xl border border-brand-accent/40 bg-card p-3 shadow-lg w-[240px]">
              <span className="font-memento-serif text-[13px]">
                {getNoteDisplayTitle(activeNote, t('notes.untitled'))}
              </span>
            </div>
          ) : null}
        </DragOverlay>
      </DndContext>
    </div>
  )
}
