
import { forwardRef, useId, useMemo, useRef, useState} from "react";
import { useAtom, useAtomValue } from "jotai";
import { autoUpdate, flip, FloatingFocusManager, FloatingPortal, size, useDismiss, useFloating, useInteractions, useListNavigation, useRole } from "@floating-ui/react";
import Fuse from "fuse.js";
import { charactersAtom, selectedTargetInventoryAtom } from "@/state/atoms";

interface AccountInventorySelectorItemProps {
  children: React.ReactNode;
  active: boolean;
}



const AccountInventorySelectorItem = forwardRef<
  HTMLDivElement,
  AccountInventorySelectorItemProps & React.HTMLProps<HTMLDivElement>
>(({ children, active, ...rest }, ref) => {
  const id = useId();
  return (
    <div
      ref={ref}
      role="option"
      id={id}
      aria-selected={active}
      {...rest}
      style={{
        background: active ? "lightblue" : "none",
        padding: 4,
        cursor: "default",
        ...rest.style,
      }}
    >
      {children}
    </div>
  );
});
export const InventoryTargetSelector = () => {
  const [open, setOpen] = useState(false);
  const [inputValue, setInputValue] = useState("");
  const [activeIndex, setActiveIndex] = useState<number | null>(null);

  const listRef = useRef<Array<HTMLElement | null>>([]);

  const { refs, floatingStyles, context } = useFloating<HTMLInputElement>({
    whileElementsMounted: autoUpdate,
    open,
    onOpenChange: setOpen,
    middleware: [
      flip({ padding: 10 }),
      size({
        apply({ rects, availableHeight, elements }) {
          Object.assign(elements.floating.style, {
            width: `${rects.reference.width}px`,
            maxHeight: `${availableHeight}px`,
          });
        },
        padding: 10,
      }),
    ],
  });

  const role = useRole(context, { role: "listbox" });
  const dismiss = useDismiss(context);
  const listNav = useListNavigation(context, {
    listRef,
    activeIndex,
    onNavigate: setActiveIndex,
    virtual: true,
    loop: true,
  });

  const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(
    [role, dismiss, listNav]
  );

  function onChange(event: React.ChangeEvent<HTMLInputElement>) {
    const value = event.target.value;
    setInputValue(value);
    setSelectedTargetInventory(undefined)

    if (value) {
      setOpen(true);
      setActiveIndex(0);
    } else {
      setOpen(false);
    }
  }
  const { data: subaccounts } = useAtomValue(charactersAtom)

  const [selectedTargetInventory, setSelectedTargetInventory] = useAtom(selectedTargetInventoryAtom)

  const searcher = useMemo(()=>{
    return new Fuse(subaccounts?.flatMap(x=>[
      x.bank,
      x.character,
    ])||[], {
        keys:["path","name"],
        findAllMatches: true,
        threshold: 0.8,
        useExtendedSearch: true,
      })
  }, [subaccounts])

  const items = searcher.search(inputValue || "!-", {limit: 10}).map(x=>x.item)
  return (
    <>
      <input
        className="border border-black-1 bg-gray-100 placeholder-gray-600"
        {...getReferenceProps({
          ref: refs.setReference,
          onChange,
          value: selectedTargetInventory !== undefined ? selectedTargetInventory.name : inputValue,
          placeholder: "Target Inventory",
          "aria-autocomplete": "list",
          onFocus() {
            setOpen(true);
          },
          onKeyDown(event) {
            if (
              event.key === "Enter" &&
                activeIndex != null &&
                items[activeIndex]
            ) {
              setSelectedTargetInventory(items[activeIndex])
              setInputValue(items[activeIndex].name);
              setActiveIndex(null);
              setOpen(false);
            }
          },
        })}
      />
      {open && (
        <FloatingPortal>
          <FloatingFocusManager
            context={context}
            initialFocus={-1}
            visuallyHiddenDismiss
          >
            <div
              {...getFloatingProps({
                ref: refs.setFloating,
                style: {
                  ...floatingStyles,
                  background: "#eee",
                  color: "black",
                  overflowY: "auto",
                },
              })}
            >
              {items.map((item, index) => (
                <AccountInventorySelectorItem
                  {...getItemProps({
                    key: item.path,
                    ref(node) {
                      listRef.current[index] = node;
                    },
                    onClick() {
                      setInputValue(item.name);
                      setSelectedTargetInventory(item);
                      setOpen(false);
                      refs.domReference.current?.focus();
                    },
                  })}
                  active={activeIndex === index}
                >
                  {item.name}
                </AccountInventorySelectorItem>
              ))}
            </div>
          </FloatingFocusManager>
        </FloatingPortal>
      )}
    </>
  );
}
