import {
  memo,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react'
import { AnimatePresence, m } from 'framer-motion'
import { ChevronDown, Plus } from 'lucide-react'

import {
  popoverVariants,
  uiFadeTransition,
} from '../../../../shared/lib/motion'

import '../../../EmployeesPage/components/OrganisationSelect/OrganisationSelect.scss'
import './MachineSelect.scss'

export type MachineSelectOption = {
  value: string
  label: string
  description?: string
  disabled?: boolean
}

type MachineSelectProps = {
  actionLabel?: string
  value: string
  options: MachineSelectOption[]
  placeholder: string
  emptyText?: string
  disabled?: boolean
  onAction?: () => void
  onChange: (value: string) => void
}

export const MachineSelect = memo(function MachineSelect({
  actionLabel,
  value,
  options,
  placeholder,
  emptyText = 'Нет доступных вариантов',
  disabled = false,
  onAction,
  onChange,
}: MachineSelectProps) {
  const rootRef = useRef<HTMLDivElement | null>(null)
  const [isOpen, setIsOpen] = useState(false)
  const selectedOption = useMemo(
    () => options.find((option) => option.value === value),
    [options, value],
  )

  useEffect(() => {
    if (!isOpen) return

    function handleDocumentMouseDown(event: MouseEvent) {
      const target = event.target as Node

      if (!rootRef.current?.contains(target)) {
        setIsOpen(false)
      }
    }

    document.addEventListener('mousedown', handleDocumentMouseDown)

    return () => {
      document.removeEventListener('mousedown', handleDocumentMouseDown)
    }
  }, [isOpen])

  useEffect(() => {
    if (disabled) {
      setIsOpen(false)
    }
  }, [disabled])

  const handleToggleOpen = useCallback(() => {
    if (disabled) return

    setIsOpen((prev) => !prev)
  }, [disabled])

  const handleSelect = useCallback((nextValue: string) => {
    onChange(nextValue)
    setIsOpen(false)
  }, [onChange])

  const handleAction = useCallback(() => {
    onAction?.()
    setIsOpen(false)
  }, [onAction])

  return (
    <div
      className={`organisation-select machine-select ${isOpen ? 'is-open' : ''}`}
      ref={rootRef}
    >
      <button
        className="organisation-select__trigger machine-select__trigger"
        type="button"
        disabled={disabled}
        onClick={handleToggleOpen}
      >
        <span className={selectedOption ? '' : 'is-placeholder'}>
          {selectedOption?.label ?? (value || placeholder)}
        </span>
        <ChevronDown size={18} />
      </button>

      <AnimatePresence initial={false}>
        {isOpen && (
          <m.div
            className="organisation-select__dropdown machine-select__dropdown"
            variants={popoverVariants}
            initial="initial"
            animate="animate"
            exit="exit"
            transition={uiFadeTransition}
          >
            <div className="organisation-select__list machine-select__list">
              {options.length === 0 && (
                <div className="organisation-select__state">
                  {emptyText}
                </div>
              )}

              {options.map((option) => {
                const isSelected = option.value === value

                return (
                  <button
                    className={`organisation-select__option machine-select__option ${
                      isSelected ? 'is-selected' : ''
                    } ${option.disabled ? 'is-disabled' : ''}`}
                    type="button"
                    key={option.value}
                    disabled={option.disabled}
                    onClick={() => handleSelect(option.value)}
                  >
                    <span>{option.label}</span>
                    {option.description && (
                      <small>{option.description}</small>
                    )}
                  </button>
                )
              })}

              {onAction && actionLabel && (
                <button
                  className="organisation-select__option machine-select__option machine-select__option--action"
                  type="button"
                  onClick={handleAction}
                >
                  <span>{actionLabel}</span>
                  <Plus size={16} />
                </button>
              )}
            </div>
          </m.div>
        )}
      </AnimatePresence>
    </div>
  )
})
