import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import Autocomplete from "@mui/material/Autocomplete";
import TextField from "@mui/material/TextField";
import CircularProgress from "@mui/material/CircularProgress";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import useDebounce from "../../hooks/useDebounce";
import {
  warehouseItemListOptions,
  type WarehouseItem,
} from "../../lib/queries/warehouse";

interface ItemPickerProps {
  value: number | null;
  onChange: (itemId: number) => void;
  itemName?: string;
}

/** Minimal option shape used to display a selected value that isn't in the
 * current search results (edit/prefill via `itemName`). */
type ItemOption = Pick<WarehouseItem, "id" | "name"> & Partial<WarehouseItem>;

export default function ItemPicker({
  value,
  onChange,
  itemName,
}: ItemPickerProps) {
  const [inputValue, setInputValue] = useState(itemName ?? "");
  // Debounce the search so the list query doesn't fire on every keystroke.
  const debouncedSearch = useDebounce(inputValue, 300);

  const { data, isFetching } = useQuery(
    warehouseItemListOptions({ search: debouncedSearch, perPage: 20 }),
  );
  const options: ItemOption[] = data?.data ?? [];

  // Show the selected value even when it isn't in the current search results
  // (e.g. prefilled via `itemName`) by synthesizing a fallback option.
  const selectedOption: ItemOption | null =
    value == null
      ? null
      : (options.find((o) => o.id === value) ?? {
          id: value,
          name: itemName ?? "",
        });

  return (
    <Autocomplete<ItemOption>
      value={selectedOption}
      inputValue={inputValue}
      onInputChange={(_, newInput) => setInputValue(newInput)}
      onChange={(_, opt) => {
        if (opt) onChange(opt.id);
      }}
      options={options}
      loading={isFetching}
      filterOptions={(x) => x}
      getOptionLabel={(o) => o.name}
      isOptionEqualToValue={(o, v) => o.id === v.id}
      noOptionsText="Žádné položky"
      renderOption={(props, option) => {
        const { key, ...rest } = props;
        return (
          <Box component="li" key={key} {...rest}>
            <Box>
              <Typography variant="body2">{option.name}</Typography>
              {(option.item_number ||
                option.available_quantity !== undefined) && (
                <Typography variant="caption" color="text.secondary">
                  {option.item_number}
                  {option.item_number && option.available_quantity !== undefined
                    ? " · "
                    : ""}
                  {option.available_quantity !== undefined
                    ? `${option.available_quantity} ${option.unit ?? ""}`
                    : ""}
                </Typography>
              )}
            </Box>
          </Box>
        );
      }}
      renderInput={(params) => (
        <TextField
          {...params}
          size="small"
          placeholder="Hledat položku..."
          slotProps={{
            input: {
              ...params.InputProps,
              endAdornment: (
                <>
                  {isFetching ? (
                    <CircularProgress color="inherit" size={18} />
                  ) : null}
                  {params.InputProps.endAdornment}
                </>
              ),
            },
          }}
        />
      )}
    />
  );
}
