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

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

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

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

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

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

const StatusMessage = styled.div`
  margin: ${({ theme }) => theme.spacing[2]} 0 0;
  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;
`;

const SelectedChip = styled.div`
  margin-top: ${({ theme }) => theme.spacing[2]};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  color: ${({ theme }) => theme.colors.text.primary};
  text-align: start;
`;

interface AssigneePickerProps {
  departmentId: string;
  value: AssignableUser | null;
  onChange: (assignee: AssignableUser | null) => void;
  label?: string;
  disabled?: boolean;
}

export const AssigneePicker: React.FC<AssigneePickerProps> = ({
  departmentId,
  value,
  onChange,
  label,
  disabled = false,
}) => {
  const { t } = useLocale();
  const [search, setSearch] = useState(value?.name ?? '');
  const [open, setOpen] = useState(false);
  const wrapperRef = useRef<HTMLDivElement>(null);

  const assignableUsersQuery = useDepartmentAssignableUsers(departmentId, search);

  useEffect(() => {
    if (value) {
      setSearch(value.name);
    }
  }, [value]);

  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(() => assignableUsersQuery.data ?? [], [assignableUsersQuery.data]);

  const handleSelect = (assignee: AssignableUser) => {
    onChange(assignee);
    setSearch(assignee.name);
    setOpen(false);
  };

  const handleClear = () => {
    onChange(null);
    setSearch('');
  };

  return (
    <Wrapper ref={wrapperRef}>
      <Input
        data-testid="ticket-assignee-input"
        label={label ?? t('tickets:fields.assignee')}
        value={search}
        onChange={(event) => {
          setSearch(event.target.value);
          setOpen(true);
          if (value && event.target.value !== value.name) {
            onChange(null);
          }
        }}
        onFocus={() => setOpen(true)}
        placeholder={t('tickets:assignee.searchPlaceholder')}
        fullWidth
        disabled={disabled}
        autoComplete="off"
      />

      {value && (
        <SelectedChip>
          {value.name} ({value.email}){' '}
          <button type="button" onClick={handleClear} style={{ marginInlineStart: 8 }}>
            {t('tickets:assignee.clear')}
          </button>
        </SelectedChip>
      )}

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