import {
  memo,
  type ChangeEvent,
  type KeyboardEvent,
  type MouseEvent,
  type PointerEvent,
  useCallback,
  useMemo,
} from 'react'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import { ChevronDown, FileText, Search, ShieldCheck, X } from 'lucide-react'

import type { EmployeeRole } from '../../../../entities/employee/model/types'

import './EmployeesToolbar.scss'

export type EmployeesSortOption = {
  value: string
  label: string
  sortField: 'ID' | 'Name' | 'Date'
  sortDirection: 'ASC' | 'DESC'
}

export const usersSortOptions: EmployeesSortOption[] = [
  {
    value: 'date-desc',
    label: 'Сначала новые',
    sortField: 'Date',
    sortDirection: 'DESC',
  },
  {
    value: 'id-asc',
    label: 'ID по возрастанию',
    sortField: 'ID',
    sortDirection: 'ASC',
  },
  {
    value: 'id-desc',
    label: 'ID по убыванию',
    sortField: 'ID',
    sortDirection: 'DESC',
  },
  {
    value: 'name-asc',
    label: 'ФИО А-Я',
    sortField: 'Name',
    sortDirection: 'ASC',
  },
  {
    value: 'name-desc',
    label: 'ФИО Я-А',
    sortField: 'Name',
    sortDirection: 'DESC',
  },
  {
    value: 'date-asc',
    label: 'Сначала старые',
    sortField: 'Date',
    sortDirection: 'ASC',
  },
]

export const organisationsSortOptions: EmployeesSortOption[] = [
  {
    value: 'date-desc',
    label: 'Сначала новые',
    sortField: 'Date',
    sortDirection: 'DESC',
  },
  {
    value: 'id-asc',
    label: 'ID по возрастанию',
    sortField: 'ID',
    sortDirection: 'ASC',
  },
  {
    value: 'id-desc',
    label: 'ID по убыванию',
    sortField: 'ID',
    sortDirection: 'DESC',
  },
  {
    value: 'name-asc',
    label: 'Название А-Я',
    sortField: 'Name',
    sortDirection: 'ASC',
  },
  {
    value: 'name-desc',
    label: 'Название Я-А',
    sortField: 'Name',
    sortDirection: 'DESC',
  },
  {
    value: 'date-asc',
    label: 'Сначала старые',
    sortField: 'Date',
    sortDirection: 'ASC',
  },
]

export type EmployeesRoleFilterOption = {
  value: 'ADMIN' | 'USER'
  label: string
}

const roleFilterOptions: EmployeesRoleFilterOption[] = [
  {
    value: 'ADMIN',
    label: 'Администратор',
  },
  {
    value: 'USER',
    label: 'Пользователь',
  },
]

type EmployeesToolbarProps = {
  addButtonText: string
  onAdd: () => void

  searchValue?: string
  onSearchChange?: (value: string) => void

  sortOptions: EmployeesSortOption[]
  selectedSort: EmployeesSortOption
  onSortChange: (option: EmployeesSortOption) => void

  showSort?: boolean
  showAddButton?: boolean
  showSecondaryAction?: boolean
  secondaryActionText?: string
  onSecondaryAction?: () => void

  roleFilter?: EmployeeRole | null
  onRoleFilterChange?: (role: EmployeeRole | null) => void

  showUserFilters?: boolean
}

export const EmployeesToolbar = memo(function EmployeesToolbar({
  addButtonText,
  onAdd,
  searchValue = '',
  onSearchChange,
  sortOptions,
  selectedSort,
  onSortChange,
  showSort = true,
  showAddButton = true,
  showSecondaryAction = false,
  secondaryActionText,
  onSecondaryAction,
  roleFilter = null,
  onRoleFilterChange,
  showUserFilters = false,
}: EmployeesToolbarProps) {
  const selectedRoleOption = useMemo(
    () =>
      roleFilterOptions.find((option) => option.value === roleFilter) ?? null,
    [roleFilter],
  )

  const handleSearchChange = useCallback((
    event: ChangeEvent<HTMLInputElement>,
  ) => {
    onSearchChange?.(event.target.value)
  }, [onSearchChange])

  const handleResetClick = useCallback((
    event: MouseEvent<HTMLSpanElement>,
  ) => {
    event.preventDefault()
    event.stopPropagation()
  }, [])

  const handleRoleResetPointerDown = useCallback((
    event: PointerEvent<HTMLSpanElement>,
  ) => {
    event.preventDefault()
    event.stopPropagation()
    onRoleFilterChange?.(null)
  }, [onRoleFilterChange])

  const handleRoleResetKeyDown = useCallback((
    event: KeyboardEvent<HTMLSpanElement>,
  ) => {
    if (event.key !== 'Enter' && event.key !== ' ') return

    event.preventDefault()
    event.stopPropagation()
    onRoleFilterChange?.(null)
  }, [onRoleFilterChange])

  return (
    <div className="devices-toolbar">
      <label className="devices-search">
        <Search size={16} />

        <input
          type="text"
          placeholder="Поиск"
          value={searchValue}
          onChange={handleSearchChange}
        />
      </label>

      <div className="devices-toolbar__right">
        {showUserFilters && (
          <DropdownMenu.Root>
            <DropdownMenu.Trigger asChild>
              <button
                className={`employees-filter-button ${
                  selectedRoleOption ? 'is-active' : ''
                }`}
                type="button"
              >
                <ShieldCheck size={17} />
                <span>{selectedRoleOption?.label ?? 'Роль'}</span>

                {selectedRoleOption ? (
                  <span
                    className="employees-filter-button__reset"
                    role="button"
                    tabIndex={0}
                    onPointerDown={handleRoleResetPointerDown}
                    onClick={handleResetClick}
                    onKeyDown={handleRoleResetKeyDown}
                    aria-label="Сбросить фильтр роли"
                  >
                    <X size={14} />
                  </span>
                ) : (
                  <ChevronDown size={16} />
                )}
              </button>
            </DropdownMenu.Trigger>

            <DropdownMenu.Portal>
              <DropdownMenu.Content
                className="employees-sort-menu"
                align="end"
                sideOffset={8}
              >
                {roleFilterOptions.map((option) => (
                  <DropdownMenu.Item
                    key={option.value}
                    className="employees-sort-menu__item"
                    onSelect={() => onRoleFilterChange?.(option.value)}
                  >
                    <span>{option.label}</span>

                    {roleFilter === option.value && (
                      <span className="employees-sort-menu__check" />
                    )}
                  </DropdownMenu.Item>
                ))}
              </DropdownMenu.Content>
            </DropdownMenu.Portal>
          </DropdownMenu.Root>
        )}

        {showSort && (
          <DropdownMenu.Root>
            <DropdownMenu.Trigger asChild>
              <button className="employees-sort" type="button">
                {selectedSort.label}

                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                  <path fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" d="M11 10h7m-7 4h5m-5 4h3M11 6h10M7 18.813C6.607 19.255 5.56 21 5 21m-2-2.187C3.393 19.255 4.44 21 5 21m0 0v-6M3 5.188C3.393 4.745 4.44 3 5 3m2 2.188C6.607 4.745 5.56 3 5 3m0 0v6" />
                </svg>
              </button>
            </DropdownMenu.Trigger>

            <DropdownMenu.Portal>
              <DropdownMenu.Content
                className="employees-sort-menu"
                align="end"
                sideOffset={8}
              >
                {sortOptions.map((option) => (
                  <DropdownMenu.Item
                    key={option.value}
                    className="employees-sort-menu__item"
                    onSelect={() => onSortChange?.(option)}
                  >
                    <span>{option.label}</span>

                    {selectedSort.value === option.value && (
                      <span className="employees-sort-menu__check" />
                    )}
                  </DropdownMenu.Item>
                ))}
              </DropdownMenu.Content>
            </DropdownMenu.Portal>
          </DropdownMenu.Root>
        )}

        {showAddButton && (
          <button
            className="add-device add-employees"
            type="button"
            onClick={onAdd}
          >
            <svg
              width="16"
              height="16"
              viewBox="0 0 16 16"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <path
                d="M4.00004 4.66683C4.00004 3.78277 4.35123 2.93493 4.97635 2.30981C5.60147 1.68469 6.44932 1.3335 7.33337 1.3335C8.21743 1.3335 9.06527 1.68469 9.6904 2.30981C10.3155 2.93493 10.6667 3.78277 10.6667 4.66683C10.6667 5.55088 10.3155 6.39873 9.6904 7.02385C9.06527 7.64897 8.21743 8.00016 7.33337 8.00016C6.44932 8.00016 5.60147 7.64897 4.97635 7.02385C4.35123 6.39873 4.00004 5.55088 4.00004 4.66683ZM3.21471 9.7815C4.28337 9.1295 5.73671 8.66683 7.33337 8.66683C7.6316 8.66683 7.92404 8.68238 8.21071 8.7135C8.32522 8.72578 8.4346 8.76752 8.52818 8.83465C8.62177 8.90178 8.69636 8.99201 8.7447 9.09654C8.79304 9.20108 8.81348 9.31635 8.80401 9.43114C8.79455 9.54592 8.75551 9.65629 8.69071 9.7515C8.23917 10.4143 7.99844 11.1981 8.00004 12.0002C8.00004 12.6135 8.13804 13.1935 8.38337 13.7115C8.43118 13.8124 8.45286 13.9237 8.44645 14.0352C8.44004 14.1467 8.40572 14.2547 8.34666 14.3495C8.2876 14.4443 8.20568 14.5227 8.10843 14.5775C8.01117 14.6324 7.90169 14.662 7.79004 14.6635L7.33337 14.6668C5.84737 14.6668 4.44337 14.5735 3.39137 14.2948C2.86804 14.1562 2.37537 13.9575 2.00204 13.6575C1.60671 13.3402 1.33337 12.8968 1.33337 12.3335C1.33337 11.8088 1.57204 11.3182 1.89604 10.9075C2.22537 10.4908 2.68071 10.1075 3.21471 9.78083V9.7815ZM12 9.3335C12.1769 9.3335 12.3464 9.40373 12.4714 9.52876C12.5965 9.65378 12.6667 9.82335 12.6667 10.0002V11.3335H14C14.1769 11.3335 14.3464 11.4037 14.4714 11.5288C14.5965 11.6538 14.6667 11.8234 14.6667 12.0002C14.6667 12.177 14.5965 12.3465 14.4714 12.4716C14.3464 12.5966 14.1769 12.6668 14 12.6668H12.6667V14.0002C12.6667 14.177 12.5965 14.3465 12.4714 14.4716C12.3464 14.5966 12.1769 14.6668 12 14.6668C11.8232 14.6668 11.6537 14.5966 11.5286 14.4716C11.4036 14.3465 11.3334 14.177 11.3334 14.0002V12.6668H10C9.82323 12.6668 9.65366 12.5966 9.52864 12.4716C9.40361 12.3465 9.33337 12.177 9.33337 12.0002C9.33337 11.8234 9.40361 11.6538 9.52864 11.5288C9.65366 11.4037 9.82323 11.3335 10 11.3335H11.3334V10.0002C11.3334 9.82335 11.4036 9.65378 11.5286 9.52876C11.6537 9.40373 11.8232 9.3335 12 9.3335Z"
                fill="white"
              />
            </svg>

            {addButtonText}
          </button>
        )}

        {showSecondaryAction && secondaryActionText && (
          <button
            className="employees-report-action"
            type="button"
            onClick={onSecondaryAction}
          >
            <FileText size={17} />
            {secondaryActionText}
          </button>
        )}
      </div>
    </div>
  )
})
