import React, { useEffect, useMemo, useRef, useState } from 'react';
import styled from 'styled-components';
import { HiSearch } from 'react-icons/hi';
import { useLocale } from '@/app/providers/LocaleProvider';
import { Input, Spinner } from '@/shared/components/ui';
import { useDepartmentCollaboratorUsers } from '@/features/tickets/hooks/useDepartmentCollaboratorUsers';
import type { AssignableUser } from '@/features/tickets/types/ticketForm.types';

const Wrapper = styled.div`
  position: relative;
  width: 100%;
`;

const SearchWrap = styled.div`
  position: relative;
  width: 100%;

  svg {
    position: absolute;
    inset-inline-start: ${({ theme }) => theme.spacing[3]};
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 16px;
    color: ${({ theme }) => theme.colors.text.tertiary};
    pointer-events: none;
  }

  input {
    padding-inline-start: calc(${({ theme }) => theme.spacing[3]} + 22px);
  }
`;

const Dropdown = styled.ul`
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  inset-inline: 0;
  margin: 0;
  padding: ${({ theme }) => theme.spacing[1]};
  list-style: none;
  max-height: 220px;
  overflow-y: auto;
  background: ${({ theme }) => theme.colors.surface};
  border: 1px solid ${({ theme }) => theme.colors.borderSoft};
  border-radius: ${({ theme }) => theme.borderRadius.md};
  box-shadow: ${({ theme }) => theme.shadows.md};
`;

const OptionButton = styled.button`
  width: 100%;
  padding: ${({ theme }) => theme.spacing[3]};
  border: none;
  border-radius: ${({ theme }) => theme.borderRadius.sm};
  background: transparent;
  text-align: start;
  cursor: pointer;
  font-size: ${({ theme }) => theme.typography.fontSize.sm};

  &:hover,
  &:focus-visible {
    background: ${({ theme }) => theme.colors.surfaceInset};
    outline: none;
  }
`;

const OptionMeta = styled.span`
  display: block;
  margin-top: 2px;
  color: ${({ theme }) => theme.colors.text.tertiary};
  font-size: ${({ theme }) => theme.typography.fontSize.xs};
`;

const StatusMessage = styled.div`
  padding: ${({ theme }) => theme.spacing[3]};
  display: flex;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[2]};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  color: ${({ theme }) => theme.colors.text.secondary};
  text-align: start;
`;

interface CollaboratorPickerProps {
  departmentId: string;
  ticketId: string;
  excludeUserIds?: string[];
  onSelect: (user: AssignableUser) => void;
  disabled?: boolean;
  embedded?: boolean;
}

export const CollaboratorPicker: React.FC<CollaboratorPickerProps> = ({
  departmentId,
  ticketId,
  excludeUserIds = [],
  onSelect,
  disabled = false,
  embedded = false,
}) => {
  const { t } = useLocale();
  const [search, setSearch] = useState('');
  const [open, setOpen] = useState(false);
  const wrapperRef = useRef<HTMLDivElement>(null);

  const usersQuery = useDepartmentCollaboratorUsers(departmentId, search, ticketId);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {
        setOpen(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  const options = useMemo(() => {
    const exclude = new Set(excludeUserIds);
    return (usersQuery.data ?? []).filter((user) => !exclude.has(user.id));
  }, [excludeUserIds, usersQuery.data]);

  const handleSelect = (user: AssignableUser) => {
    onSelect(user);
    setSearch('');
    setOpen(false);
  };

  return (
    <Wrapper ref={wrapperRef}>
      <SearchWrap>
        <HiSearch aria-hidden />
        <Input
          data-testid="ticket-collaborator-input"
          label={embedded ? undefined : t('tickets:collaborators.addLabel')}
          aria-label={t('tickets:collaborators.addLabel')}
          value={search}
          onChange={(event) => {
            setSearch(event.target.value);
            setOpen(true);
          }}
          onFocus={() => setOpen(true)}
          onKeyDown={(event) => {
            if (event.key === 'Enter' && options[0]) {
              event.preventDefault();
              handleSelect(options[0]);
            }
            if (event.key === 'Escape') {
              setOpen(false);
            }
          }}
          placeholder={t('tickets:collaborators.searchPlaceholder')}
          fullWidth
          disabled={disabled}
          autoComplete="off"
        />
      </SearchWrap>

      {open && !disabled && search.trim().length > 0 && (
        <Dropdown role="listbox">
          {usersQuery.isLoading && (
            <li>
              <StatusMessage role="status">
                <Spinner size="sm" /> {t('tickets:collaborators.loading')}
              </StatusMessage>
            </li>
          )}
          {usersQuery.isError && (
            <li>
              <StatusMessage role="alert">{t('tickets:collaborators.error')}</StatusMessage>
            </li>
          )}
          {!usersQuery.isLoading && !usersQuery.isError && options.length === 0 && (
            <li>
              <StatusMessage>{t('tickets:collaborators.searchEmpty')}</StatusMessage>
            </li>
          )}
          {options.map((user) => (
            <li key={user.id}>
              <OptionButton type="button" onClick={() => handleSelect(user)}>
                {user.name}
                <OptionMeta>{user.email}</OptionMeta>
              </OptionButton>
            </li>
          ))}
        </Dropdown>
      )}
    </Wrapper>
  );
};
