import { useToast } from '@/lib/hooks/useToast'
import {
  DndContext,
  DragEndEvent,
  KeyboardSensor,
  PointerSensor,
  closestCenter,
  useSensor,
  useSensors,
} from '@dnd-kit/core'
import {
  SortableContext,
  arrayMove,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import {
  Check,
  ExternalLink,
  FileText,
  GripVertical,
  Search,
  Settings,
  X,
} from 'lucide-react'
import { useEffect, useMemo, useRef, useState } from 'react'
import { Badge } from 'shared/ui/badge'
import { Button } from 'shared/ui/button'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from 'shared/ui/dialog'
import { Input } from 'shared/ui/input'
import { Separator } from 'shared/ui/separator'
import { useStandards } from './hooks'
import { Standard } from './types'

// Компонент для сортируемого элемента эталона
interface SortableStandardItemProps {
  standard: Standard
  onRemove: (standardId: string) => void
  isDragActive: boolean
}

function SortableStandardItem({
  standard,
  onRemove,
  isDragActive,
}: SortableStandardItemProps) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: standard.id })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition: isDragging ? 'none' : transition,
    opacity: isDragging ? 0.9 : 1,
    zIndex: isDragging ? 1000 : 'auto',
  }

  return (
    <div
      ref={setNodeRef}
      style={style}
      {...attributes}
      {...listeners}
      className={`flex cursor-grab select-none items-center gap-3 rounded-md border border-primary bg-primary/10 px-3 py-2 shadow-sm ${
        isDragging
          ? 'scale-105 shadow-lg'
          : !isDragActive
            ? 'transition-shadow duration-200 hover:shadow-md'
            : ''
      } active:cursor-grabbing`}
    >
      <div className="flex h-6 w-6 items-center justify-center text-muted-foreground">
        <GripVertical className="h-4 w-4" />
      </div>

      <div className="min-w-0 flex-1">
        <div className="flex items-center gap-3">
          <div className="min-w-20 shrink-0 text-sm font-medium text-foreground">
            {standard.protocol_name}
          </div>
          <div className="truncate text-sm text-muted-foreground">
            {standard.name}
          </div>
        </div>
      </div>

      <div className="flex shrink-0 items-center gap-4 text-xs text-muted-foreground">
        <div className="flex items-center gap-1">
          <FileText className="h-3 w-3" />
          <span className="hidden sm:inline">{standard.registry_number}</span>
        </div>
        <Badge variant="secondary" className="px-1.5 py-0.5 text-xs">
          {standard.range}
        </Badge>
      </div>

      <Button
        variant="ghost"
        size="sm"
        className="h-6 w-6 shrink-0 p-0 text-muted-foreground hover:text-destructive"
        onClick={e => {
          e.stopPropagation()
          onRemove(standard.id)
        }}
        onPointerDown={e => e.stopPropagation()}
      >
        <X className="h-4 w-4" />
      </Button>
    </div>
  )
}

interface StandardsSelectorProps {
  isOpen: boolean
  onClose: () => void
  value: string[]
  onChange: (value: string[]) => void
  maxItems?: number // Добавляем опциональный параметр
}

export function StandardsSelector({
  isOpen,
  onClose,
  value = [],
  onChange,
  maxItems = 7, // Значение по умолчанию
}: StandardsSelectorProps) {
  const [selectedStandards, setSelectedStandards] = useState<string[]>(value)
  const [isDragActive, setIsDragActive] = useState(false)

  // Синхронизируем selectedStandards с value при изменении value
  useEffect(() => {
    setSelectedStandards(value)
  }, [value])
  const [searchTerm, setSearchTerm] = useState('')
  const { error } = useToast()
  const searchInputRef = useRef<HTMLInputElement>(null)

  const { data: standards = [], isLoading, error: apiError } = useStandards()

  // Настройка сенсоров для drag-and-drop
  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 10, // Начинать перетаскивание после движения на 10px
        tolerance: 5,
        delay: 100,
      },
    }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  )

  // Обработчик начала перетаскивания
  const handleDragStart = () => {
    setIsDragActive(true)
  }

  // Обработчик завершения перетаскивания
  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event
    setIsDragActive(false)

    if (over && active.id !== over.id) {
      setSelectedStandards(items => {
        const oldIndex = items.indexOf(active.id as string)
        const newIndex = items.indexOf(over.id as string)
        return arrayMove(items, oldIndex, newIndex)
      })
    }
  }

  // Автофокус на поле поиска при открытии
  useEffect(() => {
    if (isOpen && searchInputRef.current) {
      const timer = setTimeout(() => {
        searchInputRef.current?.focus()
        const closeButton = document.querySelector(
          '[data-state="open"] button[aria-label="Close"]'
        )
        if (closeButton && document.activeElement === closeButton) {
          searchInputRef.current?.focus()
        }
      }, 150)
      return () => clearTimeout(timer)
    }
  }, [isOpen])

  // Обработка клавиш для автоматического ввода в поиск
  useEffect(() => {
    if (!isOpen) return

    const handleKeyDown = (event: KeyboardEvent) => {
      const activeElement = document.activeElement
      if (
        activeElement?.tagName === 'INPUT' ||
        activeElement?.tagName === 'TEXTAREA' ||
        activeElement?.tagName === 'BUTTON' ||
        activeElement?.getAttribute('contenteditable') === 'true'
      ) {
        return
      }

      if (
        event.ctrlKey ||
        event.metaKey ||
        event.altKey ||
        event.key === 'Tab' ||
        event.key === 'Enter' ||
        event.key === 'Escape' ||
        event.key === 'ArrowUp' ||
        event.key === 'ArrowDown' ||
        event.key === 'ArrowLeft' ||
        event.key === 'ArrowRight'
      ) {
        return
      }

      if (event.key === 'Backspace') {
        event.preventDefault()
        setSearchTerm(prev => prev.slice(0, -1))
        searchInputRef.current?.focus()
        return
      }

      if (event.key.length === 1) {
        event.preventDefault()
        setSearchTerm(prev => prev + event.key)
        searchInputRef.current?.focus()
      }
    }

    document.addEventListener('keydown', handleKeyDown)
    return () => document.removeEventListener('keydown', handleKeyDown)
  }, [isOpen])

  const filteredStandards = useMemo(() => {
    if (!searchTerm) return standards

    const searchLower = searchTerm.toLowerCase()
    return standards.filter(
      standard =>
        standard.name.toLowerCase().includes(searchLower) ||
        standard.protocol_name.toLowerCase().includes(searchLower) ||
        standard.registry_number.toLowerCase().includes(searchLower)
    )
  }, [searchTerm, standards])

  // Создаем массив выбранных эталонов в том порядке, как они выбраны
  const selectedStandardsData = selectedStandards
    .map(standardId => standards.find(standard => standard.id === standardId))
    .filter((standard): standard is Standard => standard !== undefined)

  const unselectedStandards = filteredStandards.filter(
    standard => !selectedStandards.includes(standard.id)
  )

  const isMaxReached = selectedStandards.length >= maxItems

  const toggleStandard = (standardId: string) => {
    setSelectedStandards(prev => {
      if (prev.includes(standardId)) {
        return prev.filter(id => id !== standardId)
      } else if (prev.length < maxItems) {
        return [...prev, standardId]
      } else {
        error(`Можно выбрать максимум ${maxItems} эталонов`, {
          title: 'Достигнут лимит',
        })
        return prev
      }
    })
  }

  const removeStandard = (standardId: string) => {
    setSelectedStandards(prev => prev.filter(id => id !== standardId))
  }

  const handleSave = () => {
    onChange(selectedStandards)
    onClose()
  }

  const handleClose = () => {
    setSelectedStandards(value)
    setSearchTerm('')
    onClose()
  }

  const renderStandardCard = (
    standard: Standard,
    isSelected: boolean,
    showRemoveButton = false
  ) => {
    const isDisabled = !isSelected && isMaxReached && !showRemoveButton

    return (
      <div
        key={standard.id}
        className={`flex items-center gap-3 rounded-md border px-3 py-2 transition-all duration-200 ${
          isSelected
            ? 'border-primary bg-primary/10 shadow-sm'
            : isDisabled
              ? 'border-border bg-muted/50 opacity-60'
              : 'border-border hover:border-primary/50 hover:bg-primary/5'
        } ${!showRemoveButton && !isDisabled ? 'cursor-pointer' : isDisabled ? 'cursor-not-allowed' : ''}`}
        onClick={
          !showRemoveButton && !isDisabled
            ? () => toggleStandard(standard.id)
            : undefined
        }
      >
        {!showRemoveButton && (
          <div
            className={`flex h-4 w-4 items-center justify-center rounded border transition-colors ${
              isSelected
                ? 'border-primary bg-primary'
                : isDisabled
                  ? 'border-muted-foreground/30 bg-muted'
                  : 'border-border'
            }`}
          >
            {isSelected && (
              <Check className="h-3 w-3 text-primary-foreground" />
            )}
          </div>
        )}

        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-3">
            <div
              className={`min-w-20 shrink-0 text-sm font-medium ${
                isDisabled ? 'text-muted-foreground' : 'text-foreground'
              }`}
            >
              {standard.protocol_name}
            </div>
            <div
              className={`truncate text-sm ${
                isDisabled
                  ? 'text-muted-foreground/70'
                  : 'text-muted-foreground'
              }`}
            >
              {standard.name}
            </div>
          </div>
        </div>

        <div
          className={`flex shrink-0 items-center gap-4 text-xs ${
            isDisabled ? 'text-muted-foreground/50' : 'text-muted-foreground'
          }`}
        >
          <div className="flex items-center gap-1">
            <FileText className="h-3 w-3" />
            <span className="hidden sm:inline">{standard.registry_number}</span>
          </div>
          <Badge variant="secondary" className="px-1.5 py-0.5 text-xs">
            {standard.range}
          </Badge>
        </div>

        {showRemoveButton && (
          <Button
            variant="ghost"
            size="sm"
            className="h-6 w-6 shrink-0 p-0 text-muted-foreground hover:text-destructive"
            onClick={() => removeStandard(standard.id)}
          >
            <X className="h-4 w-4" />
          </Button>
        )}
      </div>
    )
  }

  if (isLoading) {
    return (
      <Dialog open={isOpen} onOpenChange={handleClose}>
        <DialogContent className="flex max-h-[95vh] max-w-6xl flex-col overflow-hidden">
          <div className="flex h-64 items-center justify-center">
            <div className="text-center">
              <div className="mx-auto mb-2 h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent"></div>
              <p className="text-muted-foreground">Загрузка эталонов...</p>
            </div>
          </div>
        </DialogContent>
      </Dialog>
    )
  }

  if (apiError) {
    return (
      <Dialog open={isOpen} onOpenChange={handleClose}>
        <DialogContent className="flex max-h-[95vh] max-w-6xl flex-col overflow-hidden">
          <div className="flex h-64 items-center justify-center">
            <div className="text-center">
              <p className="mb-2 text-destructive">Ошибка загрузки эталонов</p>
              <p className="text-sm text-muted-foreground">
                {apiError.message}
              </p>
            </div>
          </div>
        </DialogContent>
      </Dialog>
    )
  }

  return (
    <Dialog open={isOpen} onOpenChange={handleClose}>
      <DialogContent className="flex max-h-[95vh] max-w-6xl flex-col overflow-hidden">
        <DialogHeader className="shrink-0 pb-3">
          <div className="flex items-center justify-between">
            <DialogTitle className="flex items-center gap-2 text-lg">
              <Settings className="h-5 w-5" />
              Измерительные эталоны
              <span
                className={`text-sm font-normal ${
                  isMaxReached ? 'text-orange-600' : 'text-muted-foreground'
                }`}
              >
                ({selectedStandards.length}/{maxItems})
              </span>
            </DialogTitle>
          </div>
        </DialogHeader>

        <div className="flex flex-1 flex-col space-y-4 overflow-hidden">
          {/* Поиск и ссылка на управление */}
          <div className="flex shrink-0 gap-2">
            <div className="relative flex-1">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                ref={searchInputRef}
                placeholder="Начните печатать для поиска..."
                value={searchTerm}
                onChange={e => setSearchTerm(e.target.value)}
                className="pl-10"
                autoComplete="off"
                autoFocus
              />
              {searchTerm && (
                <Button
                  variant="ghost"
                  size="sm"
                  className="absolute right-2 top-1/2 h-6 w-6 -translate-y-1/2 p-0"
                  onClick={() => {
                    setSearchTerm('')
                    searchInputRef.current?.focus()
                  }}
                >
                  <X className="h-3 w-3" />
                </Button>
              )}
            </div>
            <Button
              variant="outline"
              onClick={() => {
                // Открыть страницу управления эталонами
                window.open('/standards-management', '_blank')
              }}
              className="shrink-0"
            >
              <ExternalLink className="mr-2 h-4 w-4" />
              Управление
            </Button>
          </div>

          {/* Контент с прокруткой */}
          <div className="flex-1 space-y-4 overflow-y-auto">
            {/* Выбранные эталоны */}
            {selectedStandardsData.length > 0 && (
              <div>
                <h4 className="mb-3 text-sm font-medium text-foreground">
                  Выбранные эталоны ({selectedStandardsData.length})
                  <span className="ml-2 text-xs text-muted-foreground">
                    Перетащите для изменения порядка
                  </span>
                </h4>
                <div className="max-h-64 space-y-1 overflow-y-auto">
                  <DndContext
                    sensors={sensors}
                    collisionDetection={closestCenter}
                    onDragStart={handleDragStart}
                    onDragEnd={handleDragEnd}
                  >
                    <SortableContext
                      items={selectedStandards}
                      strategy={verticalListSortingStrategy}
                    >
                      {selectedStandardsData.map(standard => (
                        <SortableStandardItem
                          key={standard.id}
                          standard={standard}
                          onRemove={removeStandard}
                          isDragActive={isDragActive}
                        />
                      ))}
                    </SortableContext>
                  </DndContext>
                </div>
              </div>
            )}

            {selectedStandardsData.length > 0 &&
              unselectedStandards.length > 0 && <Separator />}

            {/* Доступные эталоны */}
            {unselectedStandards.length > 0 && (
              <div>
                <h4 className="mb-3 text-sm font-medium text-foreground">
                  Доступные эталоны ({unselectedStandards.length})
                  {isMaxReached && (
                    <span className="ml-2 text-xs text-orange-600">
                      Достигнут лимит выбора
                    </span>
                  )}
                </h4>
                <div className="space-y-1">
                  {unselectedStandards.map(standard =>
                    renderStandardCard(standard, false)
                  )}
                </div>
              </div>
            )}

            {filteredStandards.length === 0 && searchTerm && (
              <div className="py-8 text-center text-muted-foreground">
                Эталоны не найдены по запросу "{searchTerm}"
              </div>
            )}

            {standards.length === 0 && !searchTerm && (
              <div className="py-8 text-center text-muted-foreground">
                <Settings className="mx-auto mb-2 h-8 w-8 opacity-50" />
                Эталоны не созданы
              </div>
            )}
          </div>
        </div>

        {/* Зафиксированные кнопки */}
        <div className="mt-4 shrink-0 border-t pt-3">
          <div className="flex justify-end gap-2">
            <Button variant="outline" onClick={handleClose} size="sm">
              Отмена
            </Button>
            <Button onClick={handleSave} size="sm">
              Сохранить
            </Button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  )
}
