import { type SyntheticEvent, useMemo, useState } from 'react';
import { type SxProps, type Theme } from '@material-hu/mui/styles';
import { type ControllerProps, useFormContext } from 'react-hook-form';

import HuAvatar from '@material-hu/components/design-system/Avatar';
import HuFormAutocomplete, {
  type FormAutocompleteProps,
} from '@material-hu/components/design-system/Inputs/Autocomplete/form';
import HuMenuItem from '@material-hu/components/design-system/Menu/components/MenuItem';
import HuTitle from '@material-hu/components/design-system/Title';

import { useUserPotentialBossesSearch } from 'src/services/usersQueries';
import { type User, UserStatus } from 'src/types/user';
import { getFullname } from 'src/utils/userUtils';

type UserOption = User & { label: string; value: number };

const toOptions = (users: User[]): UserOption[] =>
  users.map(user => ({
    ...user,
    label: getFullname(user),
    value: user.id,
  }));

type Props = {
  name: string;
  potentialBossesId: number;
  rules?: ControllerProps['rules'];
  autocompleteProps?: FormAutocompleteProps<UserOption>['autocompleteProps'];
};

function HugoPotentialBossAutocomplete({
  name,
  potentialBossesId,
  rules,
  autocompleteProps,
}: Props) {
  const [search, setSearch] = useState('');
  const { getValues } = useFormContext();

  const { data, isLoading } = useUserPotentialBossesSearch(
    { userId: potentialBossesId, search },
    { enabled: !!search },
  );

  const options = useMemo(() => {
    const fetched = toOptions(data?.data.items || []);
    const currentValue = getValues(name) as UserOption | null;
    if (currentValue?.id && !fetched.some(o => o.id === currentValue.id)) {
      return [currentValue, ...fetched];
    }
    return fetched;
  }, [data?.data.items, getValues, name]);

  const { slotProps: callerSlotProps, ...restAutocompleteProps } =
    autocompleteProps ?? {};

  return (
    <HuFormAutocomplete
      name={name}
      rules={rules}
      options={options}
      autocompleteProps={{
        isOptionEqualToValue: (option: UserOption, value: UserOption) =>
          option.id === value.id,
        renderOption: (
          props: React.HTMLAttributes<HTMLLIElement> & { key: React.Key },
          option: UserOption,
        ) => {
          const { key, ...rest } = props;
          if (option.status === UserStatus.DEACTIVATED) return null;
          return (
            <HuMenuItem
              key={key}
              {...rest}
              sx={{ gap: 2 }}
            >
              <HuAvatar
                src={option.profilePicture || undefined}
                size="medium"
                sx={{ my: 1 }}
              />
              <HuTitle
                variant="S"
                title={getFullname(option)}
                description={option.employeeInternalId}
              />
            </HuMenuItem>
          );
        },
        onInputChange: (_: SyntheticEvent, value: string) =>
          setSearch(value || ' '),
        loading: isLoading,
        isServerFiltered: true,
        // Popper must render above DialogLayer dialogs (z-index: 1400+).
        // Merge defensively so callers can extend popper sx without wiping this.
        slotProps: {
          ...callerSlotProps,
          popper: {
            ...callerSlotProps?.popper,
            sx: [
              theme => ({ zIndex: theme.zIndex.modal + 200 }),
              callerSlotProps?.popper?.sx,
            ] as SxProps<Theme>,
          },
        },
        ...restAutocompleteProps,
      }}
    />
  );
}

export default HugoPotentialBossAutocomplete;
