import { useState, useRef, useEffect, useCallback, useId } from "react";
import { createPortal } from "react-dom";
import { useQuery } from "@tanstack/react-query";
import { warehouseItemListOptions } from "../../lib/queries/warehouse";

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

export default function ItemPicker({
  value,
  onChange,
  itemName,
}: ItemPickerProps) {
  const [search, setSearch] = useState(itemName ?? "");
  const [open, setOpen] = useState(false);
  const { data } = useQuery(warehouseItemListOptions({ search, perPage: 20 }));
  const items = data?.data ?? [];

  const containerRef = useRef<HTMLDivElement>(null);
  const activeIndexRef = useRef<number>(-1);
  const listboxId = useId();
  const [activeIndex, setActiveIndex] = useState<number>(-1);

  const [dropdownStyle, setDropdownStyle] = useState<{
    position: "fixed";
    top: number;
    left: number;
    width: number;
    zIndex: number;
  } | null>(null);

  const updatePosition = useCallback(() => {
    if (!containerRef.current) return;
    const rect = containerRef.current.getBoundingClientRect();
    setDropdownStyle({
      position: "fixed",
      top: rect.bottom + 2,
      left: rect.left,
      width: rect.width,
      zIndex: 100,
    });
  }, []);

  // Reset active index when items change
  useEffect(() => {
    if (activeIndex >= items.length) {
      activeIndexRef.current = -1;
      setActiveIndex(-1);
    }
  }, [items, activeIndex]);

  useEffect(() => {
    if (open) {
      updatePosition();
      const onScroll = () => updatePosition();
      const onClose = () => setOpen(false);
      window.addEventListener("scroll", onScroll, true);
      window.addEventListener("resize", onClose);
      return () => {
        window.removeEventListener("scroll", onScroll, true);
        window.removeEventListener("resize", onClose);
      };
    } else {
      setDropdownStyle(null);
      activeIndexRef.current = -1;
      setActiveIndex(-1);
    }
  }, [open, updatePosition]);

  // Close on click-outside via mousedown on document
  useEffect(() => {
    if (!open) return;
    const onDocMouseDown = (e: MouseEvent) => {
      const target = e.target;
      if (containerRef.current && target instanceof Node) {
        if (!containerRef.current.contains(target)) {
          // Don't close if click landed on an option in the portal
          const listEl = document.getElementById(listboxId);
          if (listEl && listEl.contains(target)) return;
          setOpen(false);
        }
      }
    };
    document.addEventListener("mousedown", onDocMouseDown);
    return () => document.removeEventListener("mousedown", onDocMouseDown);
  }, [open, listboxId]);

  const handleSelect = (itemId: number, name: string) => {
    onChange(itemId);
    setOpen(false);
    setSearch(name);
  };

  const setActive = (index: number) => {
    activeIndexRef.current = index;
    setActiveIndex(index);
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "ArrowDown") {
      e.preventDefault();
      if (!open) {
        setOpen(true);
        if (items.length > 0) setActive(0);
        return;
      }
      const next =
        activeIndexRef.current < items.length - 1
          ? activeIndexRef.current + 1
          : 0;
      setActive(next);
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      if (!open) {
        setOpen(true);
        if (items.length > 0) setActive(items.length - 1);
        return;
      }
      const prev =
        activeIndexRef.current > 0
          ? activeIndexRef.current - 1
          : items.length - 1;
      setActive(prev);
    } else if (e.key === "Enter") {
      if (
        open &&
        activeIndexRef.current >= 0 &&
        activeIndexRef.current < items.length
      ) {
        e.preventDefault();
        const item = items[activeIndexRef.current];
        handleSelect(item.id, item.name);
      }
    } else if (e.key === "Escape") {
      if (open) {
        e.preventDefault();
        setOpen(false);
      }
    } else if (e.key === "Home") {
      if (open && items.length > 0) {
        e.preventDefault();
        setActive(0);
      }
    } else if (e.key === "End") {
      if (open && items.length > 0) {
        e.preventDefault();
        setActive(items.length - 1);
      }
    } else if (e.key === "Tab") {
      setOpen(false);
    }
  };

  const activeId =
    activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : undefined;

  return (
    <div
      ref={containerRef}
      style={{ position: "relative" }}
      role="combobox"
      aria-haspopup="listbox"
      aria-expanded={open}
      aria-owns={listboxId}
    >
      <input
        type="text"
        className="admin-form-input"
        placeholder="Hledat položku..."
        value={search}
        role="searchbox"
        aria-autocomplete="list"
        aria-controls={listboxId}
        aria-activedescendant={activeId}
        onChange={(e) => {
          setSearch(e.target.value);
          setOpen(true);
        }}
        onFocus={() => {
          setOpen(true);
          updatePosition();
        }}
        onKeyDown={handleKeyDown}
      />
      {open &&
        items.length > 0 &&
        dropdownStyle &&
        createPortal(
          <ul
            id={listboxId}
            role="listbox"
            className="admin-item-picker-list"
            style={dropdownStyle}
          >
            {items.map((item, index) => (
              <li
                key={item.id}
                id={`${listboxId}-option-${index}`}
                role="option"
                aria-selected={value === item.id}
                className={`admin-item-picker-item ${activeIndex === index ? "active" : ""}`}
                onMouseDown={(e) => {
                  e.preventDefault();
                  handleSelect(item.id, item.name);
                }}
              >
                <span className="admin-item-picker-name">{item.name}</span>
                {item.item_number && (
                  <span className="admin-item-picker-number">
                    {item.item_number}
                  </span>
                )}
                {item.available_quantity !== undefined && (
                  <span className="admin-item-picker-qty">
                    {item.available_quantity} {item.unit}
                  </span>
                )}
              </li>
            ))}
          </ul>,
          document.body,
        )}
    </div>
  );
}
