import { useState, type CSSProperties, useMemo } from "react";
import Icon from "./icon";
import "./SelectRecipeMenu.css";
import Tooltip from "./Tooltip";
import SimpleBar from "simplebar-react";
import "simplebar-react/dist/simplebar.min.css";

// Utility type definitions
export type Category<T> = {
  name: string;
  icon: string;
  subGroup: SubGroup<T>[];
};
export type SubGroup<T> = {
  name: string;
  order?: string;
  children: Array<T>;
};
export type MenuItem = { name: string; icon: string };

interface SubGroupProps {
  subgroup: SubGroup<MenuItem>;
  selectedItem: string;
  onSelectItem: (name: string) => void;
}

// Constants
const ITEM_PER_ROW = 10;

/**
 * Return a new `Category` object that contains only
 * sub‑groups and items that match the search string.
 * @param category the original category
 * @param search the user’s search query
 * @returns a filtered copy of the category
 */
function filterCategory(category: Category<MenuItem>, search: string): Category<MenuItem> {
  const searchKeys = search.toLowerCase().split(" ");

  // Filter the children inside a single sub‑group
  function filterSubgroupChildren(subgroup: SubGroup<MenuItem>): SubGroup<MenuItem> {
    const children = subgroup.children.filter((item) => searchKeys.every((k) => item.name.includes(k)));
    return {
      ...subgroup,
      children,
    };
  }
  return {
    ...category,
    subGroup: category.subGroup.map(filterSubgroupChildren).filter((s) => s.children.length > 0),
  };
}

function SubGroupRow({ subgroup, selectedItem, onSelectItem }: SubGroupProps) {
  const emptySlotsCounts = useMemo(() => {
    const lastRowSlots = subgroup.children.length % ITEM_PER_ROW;
    return lastRowSlots > 0 ? ITEM_PER_ROW - lastRowSlots : 0;
  }, [subgroup]);
  return (
    <div className="select-menu-content-row">
      {subgroup.children.map((o) => (
        <Tooltip title={o.name} key={o.name}>
          <div
            className={"select-menu-icon " + (o.name == selectedItem ? "active" : "")}
            onClick={() => onSelectItem(o.name)}
          >
            <Icon iconName={o.icon} size={30}></Icon>
          </div>
        </Tooltip>
      ))}
      {Array(emptySlotsCounts)
        .fill(0)
        .map((_, i) => (
          <div className="select-menu-slot" key={i}>
            <div className="select-menu-slot-empty"></div>
          </div>
        ))}
    </div>
  );
}

type SelectMenuProps = {
  categories: Category<MenuItem>[];
  className?: string;
  title?: string;
  style?: CSSProperties;
  onClose?: () => void;
  onSelectItem?: (itemName: string) => void;
};
function SelectMenu({ style, className, title, categories, onClose, onSelectItem }: SelectMenuProps) {
  const [category, setCategory] = useState(categories[0].name);
  const [item, selectItem] = useState("");
  const [showSearch, setShowSearch] = useState(false);
  const [search, setSearch] = useState("");

  const activeCategory = useMemo(() => categories.find((r) => r.name == category), [category, categories]);
  const activeOnSelect = useMemo(() => (onSelectItem ? onSelectItem : selectItem), [onSelectItem, selectItem]);
  // Apply filtering only if a search is active
  const filteredContent = useMemo(
    () => (search && activeCategory && showSearch ? filterCategory(activeCategory, search) : activeCategory),
    [activeCategory, search, showSearch]
  );
  return (
    <div style={style} className={"select-menu " + className}>
      <div className="select-menu-header">
        <div className="select-menu-header-title">{title ?? "Title"}</div>
        <div className="select-menu-header-spacer"></div>
        <div className="select-menu-header-action">
          {showSearch && <input type="search" onChange={(evt) => setSearch(evt.target.value)} value={search}></input>}
          <button className={"panel-button " + (showSearch ? "active" : "")} onClick={() => setShowSearch(!showSearch)}>
            <img src="/assets/search.png" />
          </button>
          <button className="panel-button" onClick={onClose}>
            <img src="/assets/close.png" />
          </button>
        </div>
      </div>
      <div className="select-menu-group">
        {categories.map((g) => (
          <div
            className={"select-menu-group-icon " + (g.name == category ? "active" : "")}
            onClick={() => setCategory(g.name)}
            key={g.name}
          >
            <Icon iconName={g.icon} size={62}></Icon>
          </div>
        ))}
      </div>
      <div className="select-menu-content">
        <SimpleBar style={{ maxHeight: 300 }}>
          {filteredContent?.subGroup.map((subgroup) => (
            <SubGroupRow
              subgroup={subgroup}
              selectedItem={item}
              onSelectItem={activeOnSelect}
              key={subgroup.name}
            ></SubGroupRow>
          ))}
        </SimpleBar>
      </div>
    </div>
  );
}
export default SelectMenu;
