'use client'

import {
  Copy,
  Eye,
  EyeOff,
  GripVertical,
  Lock,
  type LucideIcon,
  MoreVertical,
  Plus,
  Trash2,
} from 'lucide-react'
import {
  DndContext,
  KeyboardSensor,
  PointerSensor,
  closestCenter,
  useSensor,
  useSensors,
  type DragEndEvent,
} from '@dnd-kit/core'
import {
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import { adminPortalContainer } from '../../lib/portal-container.js'
import type { PageSection } from '../../lib/page-editor-service.js'
import { sectionIconFor } from './section-icons.js'

interface SectionsPanelProps {
  sections: PageSection[]
  selectedId: string | null
  canEdit: boolean
  onSelect: (id: string) => void
  onReorder: (orderedIds: string[]) => void
  onToggleVisibility: (id: string) => void
  onDuplicate: (id: string) => void
  onRequestDelete: (id: string) => void
  onAdd: () => void
}

export function SectionsPanel({
  sections,
  selectedId,
  canEdit,
  onSelect,
  onReorder,
  onToggleVisibility,
  onDuplicate,
  onRequestDelete,
  onAdd,
}: SectionsPanelProps) {
  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
  )

  function handleDragEnd(event: DragEndEvent) {
    const { active, over } = event
    if (!over || active.id === over.id) return
    const ids = sections.map((s) => s.id)
    const from = ids.indexOf(String(active.id))
    const to = ids.indexOf(String(over.id))
    if (from === -1 || to === -1) return
    const next = ids.slice()
    const [moved] = next.splice(from, 1)
    next.splice(to, 0, moved!)
    onReorder(next)
  }

  return (
    <aside
      className="bg-card border-border flex h-full w-72 shrink-0 flex-col border-r"
      aria-label="Page sections"
    >
      <div className="border-border flex items-center justify-between border-b px-4 py-3">
        <div className="flex items-center gap-2">
          <h2 className="text-foreground text-sm font-medium">Sections</h2>
          <span className="bg-muted text-muted-foreground rounded-full px-2 py-0.5 text-xs font-medium tabular-nums">
            {sections.length}
          </span>
        </div>
      </div>

      <div className="flex-1 overflow-y-auto p-2">
        {sections.length === 0 ? (
          <p className="text-muted-foreground px-2 py-6 text-center text-sm">
            No sections yet. Add one below to get started.
          </p>
        ) : (
          <DndContext
            sensors={sensors}
            collisionDetection={closestCenter}
            onDragEnd={handleDragEnd}
          >
            <SortableContext
              items={sections.map((s) => s.id)}
              strategy={verticalListSortingStrategy}
            >
              <ul className="space-y-1">
                {sections.map((section) => (
                  <SortableSectionItem
                    key={section.id}
                    section={section}
                    selected={section.id === selectedId}
                    canEdit={canEdit}
                    onSelect={onSelect}
                    onToggleVisibility={onToggleVisibility}
                    onDuplicate={onDuplicate}
                    onRequestDelete={onRequestDelete}
                  />
                ))}
              </ul>
            </SortableContext>
          </DndContext>
        )}
      </div>

      <div className="border-border border-t p-3">
        <button
          type="button"
          onClick={onAdd}
          disabled={!canEdit}
          className="border-border text-foreground hover:bg-accent flex w-full items-center justify-center gap-2 rounded-lg border border-dashed px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50"
        >
          <Plus className="h-4 w-4" aria-hidden />
          Add Section
        </button>
      </div>
    </aside>
  )
}

interface SortableItemProps {
  section: PageSection
  selected: boolean
  canEdit: boolean
  onSelect: (id: string) => void
  onToggleVisibility: (id: string) => void
  onDuplicate: (id: string) => void
  onRequestDelete: (id: string) => void
}

function SortableSectionItem({
  section,
  selected,
  canEdit,
  onSelect,
  onToggleVisibility,
  onDuplicate,
  onRequestDelete,
}: SortableItemProps) {
  // Unmanaged (externally-managed) sections are read-only: no drag, duplicate,
  // delete, or visibility toggle — only selectable to view the read-only notice.
  const locked = section.unmanaged === true
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
    id: section.id,
    disabled: !canEdit || locked,
  })
  const Icon = sectionIconFor(section.sectionType)

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    zIndex: isDragging ? 10 : undefined,
  }

  return (
    <li ref={setNodeRef} style={style}>
      <div
        className={`group flex items-center gap-2 rounded-lg border px-2 py-2 ${
          selected ? 'border-primary bg-accent' : 'hover:bg-accent/60 border-transparent'
        } ${isDragging ? 'shadow-md' : ''}`}
      >
        <button
          type="button"
          className="text-muted-foreground hover:text-foreground shrink-0 cursor-grab touch-none disabled:cursor-not-allowed disabled:opacity-40"
          aria-label={`Drag to reorder ${section.name}`}
          disabled={!canEdit || locked}
          {...attributes}
          {...listeners}
        >
          <GripVertical className="h-4 w-4" aria-hidden />
        </button>

        <button
          type="button"
          onClick={() => onSelect(section.id)}
          className="flex min-w-0 flex-1 items-center gap-2 text-left"
        >
          <span className="bg-muted text-muted-foreground flex h-7 w-7 shrink-0 items-center justify-center rounded-md">
            <Icon className="h-4 w-4" aria-hidden />
          </span>
          <span
            className={`truncate text-sm ${section.visible ? 'text-foreground' : 'text-muted-foreground line-through'}`}
          >
            {section.name}
          </span>
        </button>

        {locked ? (
          <span
            className="text-muted-foreground shrink-0 p-1"
            title="Managed outside the editor — read-only"
            aria-label={`${section.name} is managed outside the editor and is read-only`}
          >
            <Lock className="h-4 w-4" aria-hidden />
          </span>
        ) : (
          <>
            <button
              type="button"
              onClick={() => onToggleVisibility(section.id)}
              disabled={!canEdit}
              aria-pressed={!section.visible}
              aria-label={section.visible ? `Hide ${section.name}` : `Show ${section.name}`}
              className="text-muted-foreground hover:text-foreground shrink-0 rounded p-1 disabled:opacity-40"
            >
              {section.visible ? (
                <Eye className="h-4 w-4" aria-hidden />
              ) : (
                <EyeOff className="h-4 w-4" aria-hidden />
              )}
            </button>

            <DropdownMenu.Root>
              <DropdownMenu.Trigger asChild>
                <button
                  type="button"
                  disabled={!canEdit}
                  aria-label={`More actions for ${section.name}`}
                  className="text-muted-foreground hover:text-foreground shrink-0 rounded p-1 disabled:opacity-40"
                >
                  <MoreVertical className="h-4 w-4" aria-hidden />
                </button>
              </DropdownMenu.Trigger>
              <DropdownMenu.Portal container={adminPortalContainer()}>
                <DropdownMenu.Content
                  align="end"
                  sideOffset={4}
                  className="border-border bg-popover z-[70] min-w-44 rounded-lg border p-1 shadow-md"
                >
                  <MenuItem onSelect={() => onDuplicate(section.id)} icon={Copy}>
                    Duplicate
                  </MenuItem>
                  <DropdownMenu.Separator className="bg-border my-1 h-px" />
                  <MenuItem onSelect={() => onRequestDelete(section.id)} icon={Trash2} destructive>
                    Delete
                  </MenuItem>
                </DropdownMenu.Content>
              </DropdownMenu.Portal>
            </DropdownMenu.Root>
          </>
        )}
      </div>
    </li>
  )
}

function MenuItem({
  children,
  icon: Icon,
  onSelect,
  destructive,
}: {
  children: React.ReactNode
  icon: LucideIcon
  onSelect: () => void
  destructive?: boolean
}) {
  return (
    <DropdownMenu.Item
      onSelect={onSelect}
      className={`flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none ${
        destructive ? 'text-destructive focus:bg-destructive/10' : 'text-foreground focus:bg-accent'
      }`}
    >
      <Icon className="h-4 w-4" aria-hidden />
      {children}
    </DropdownMenu.Item>
  )
}
