import { Button, MenuItem, Checkbox, ListItemText } from "@suid/material";
import { createMemo, createSignal, createUniqueId, For } from "solid-js";
import Menu from "../material/Menu";
import { FilterList, FilterListOff } from "@suid/icons-material";

type Props<Filters extends Record<string, string>> = {
  options: Filters;
  applied: Record<keyof Filters, boolean | undefined>;
  disabledKeys?: (keyof Filters)[];

  onApply(value: Record<keyof Filters, boolean | undefined>): void;
};

function TootFilterButton<F extends Record<string, string>>(props: Props<F>) {
  const buttonId = createUniqueId();
  const [open, setOpen] = createSignal(false);

  const getTextForMultipleEntities = (texts: string[]) => {
    switch (texts.length) {
      case 0:
        return "Nothing";
      case 1:
        return texts[0];
      case 2:
        return `${texts[0]} and ${texts[1]}`;
      case 3:
        return `${texts[0]}, ${texts[1]} and ${texts[2]}`;
      default:
        return `${texts[0]} and ${texts.length - 1} other${texts.length > 2 ? "s" : ""}`;
    }
  };

  const optionKeys = () => Object.keys(props.options);

  const appliedKeys = createMemo(() => {
    const applied = props.applied;
    return optionKeys().filter((k) => applied[k]);
  });

  const text = () => {
    const keys = optionKeys();
    const napplied = appliedKeys().length;
    switch (napplied) {
      case keys.length:
        return "All";
      default:
        return getTextForMultipleEntities(
          appliedKeys().map((k) => props.options[k]),
        );
    }
  };

  const toggleKey = (key: keyof F) => {
    props.onApply(
      Object.assign({}, props.applied, {
        [key]: !props.applied[key],
      }),
    );
  };

  let anchor: { left: number; top: number; right: number };

  const onClick = (event: MouseEvent) => {
    anchor = {
      left: event.clientX,
      right: event.clientX,
      top: event.clientY,
    };
    setOpen(true);
  };

  return (
    <>
      <Button size="large" onClick={onClick} id={buttonId}>
        {appliedKeys().length === optionKeys().length ? (
          <FilterListOff />
        ) : (
          <FilterList />
        )}

        <span style={{ "margin-left": "0.5em" }}>{text()}</span>
      </Button>
      <Menu open={open()} onClose={[setOpen, false]} anchor={() => anchor}>
        <For each={Object.keys(props.options)}>
          {(item, idx) => (
            <>
              <MenuItem
                data-sort={idx()}
                onClick={[toggleKey, item]}
                disabled={props.disabledKeys?.includes(item)}
              >
                <ListItemText>{props.options[item]}</ListItemText>
                <Checkbox
                  checked={props.applied[item]}
                  sx={{ marginRight: "-8px" }}
                  disabled={props.disabledKeys?.includes(item)}
                ></Checkbox>
              </MenuItem>
            </>
          )}
        </For>
      </Menu>
    </>
  );
}

export default TootFilterButton;
