'use client';
import { FunctionComponent, useState } from 'react';
import Autocomplete from '@mui/material/Autocomplete';
import Box from '@mui/material/Box';
import CircularProgress from '@mui/material/CircularProgress';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import { useUserSearch } from '@/services/admin';
import { useDebouncedValue } from '@/services/search';
import type { AdminUserSummary, DirectoryUserRole } from '@/services/admin/types';

export interface UserPickerProps {
  value: AdminUserSummary | null;
  onChange: (user: AdminUserSummary | null) => void;
  /** Already-translated field label. */
  label: string;
  placeholder?: string;
  helperText?: string;
  noOptionsText?: string;
  loadingText?: string;
  /** Narrow the search to one coarse role (`NursePicker` passes `'nurse'`). */
  roleFilter?: DirectoryUserRole;
  disabled?: boolean;
  error?: boolean;
}

const SEARCH_DEBOUNCE_MS = 300;

/**
 * Async name/phone search over the admin user directory (REQ-061, gap — mock-backed until delivered),
 * replacing every raw numeric-id `TextField` on an audited action (role grants, partner-center admin
 * assignment, sponsored-nurse assignment, alert assignment — phase §3.2). Each option renders
 * **name + masked phone + `#id`**, never a bare id, so the caller's confirm dialog can echo a resolved
 * **person** instead of `#42`. `NursePicker` is a thin `roleFilter="nurse"` wrapper over this component.
 * @component UserPicker
 */
const UserPicker: FunctionComponent<UserPickerProps> = ({
  value,
  onChange,
  label,
  placeholder,
  helperText,
  noOptionsText,
  loadingText,
  roleFilter,
  disabled,
  error,
}) => {
  const [inputValue, setInputValue] = useState('');
  const debouncedQuery = useDebouncedValue(inputValue, SEARCH_DEBOUNCE_MS);
  const search = useUserSearch(debouncedQuery, roleFilter);
  const options = search.data ?? [];

  return (
    <Autocomplete
      value={value}
      onChange={(_event, next) => onChange(next)}
      inputValue={inputValue}
      onInputChange={(_event, next) => setInputValue(next)}
      options={options}
      loading={search.isFetching}
      disabled={disabled}
      // The directory is already narrowed server-side (mock or real) — never re-filter client-side.
      filterOptions={(opts) => opts}
      getOptionLabel={(option) => option.displayName}
      isOptionEqualToValue={(option, selected) => option.id === selected.id}
      noOptionsText={noOptionsText}
      loadingText={loadingText}
      renderOption={(optionProps, option) => {
        const { key, ...rest } = optionProps;
        return (
          <Box component="li" key={key} {...rest}>
            <Stack sx={{ gap: 0.125, py: 0.25 }}>
              <Typography variant="body2" sx={{ fontWeight: 500 }}>
                {option.displayName}
              </Typography>
              <Typography component="span" variant="caption" dir="ltr" sx={{ color: 'text.secondary' }}>
                {option.maskedPhone} · #{option.id}
              </Typography>
            </Stack>
          </Box>
        );
      }}
      renderInput={({ slotProps: autocompleteSlotProps, ...rest }) => (
        <TextField
          {...rest}
          label={label}
          placeholder={placeholder}
          helperText={helperText}
          error={error}
          slotProps={{
            ...autocompleteSlotProps,
            input: {
              ...autocompleteSlotProps.input,
              endAdornment: (
                <>
                  {search.isFetching ? <CircularProgress color="inherit" size={16} /> : null}
                  {autocompleteSlotProps.input.endAdornment}
                </>
              ),
            },
          }}
        />
      )}
    />
  );
};

export default UserPicker;
