// TODO: Update DropdownProps["value"] so the type matches SelectHTMLAttributes["value"]
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { ReactNode, SyntheticEvent, useCallback } from "react";
import classNames from "classnames";
import selfless from "@komi-app/selfless";
import When from "@komi-app/when";

import styles from "./dropdownMenuItem.module.scss";
import { DropdownItem } from "../../Dropdown";
import { MdCheckBoxOutlineBlank as CheckBoxOutlineBlank, MdCheckBox as CheckBox } from "react-icons/md";
import { Tag, TagProps } from "@komi-app/creator-ui";

export interface DropdownMenuItemProps {
  name: string;
  multiple?: boolean;
  current?: DropdownItem;
  item: DropdownItem;
  selectedItems?: DropdownItem[];
  onChange: (value: DropdownItem, remove?: boolean) => void;
}

export interface DropdownMenuItemViewProps {
  name: string;
  label: string;
  value?: any;
  checked?: boolean;
  type: Type;
  containerClassName: string;
  menuItemClassName: string;
  prefixIcon?: ReactNode;
  suffixIcon?: ReactNode;
  change: (e: SyntheticEvent<HTMLInputElement, Event>) => void;
  click: (e: React.MouseEvent<HTMLInputElement>) => void;
  tagProps?: TagProps;
  multiple?: boolean;
}

export enum Type {
  RADIO = "radio",
  CHECKBOX = "checkbox",
}

export function useDropdownMenuItem({
  item,
  current,
  multiple,
  selectedItems,
  onChange,
  ...props
}: DropdownMenuItemProps): DropdownMenuItemViewProps {
  let value;
  let text;
  let disabled;
  let prefixIcon;
  let suffixIcon;
  let tagProps;

  if (typeof item === "string") {
    value = item;
  } else {
    ({ value, disabled, prefixIcon, suffixIcon, tagProps, label: text } = item);
  }

  const isCurrent = current === item;
  const checked = selectedItems?.includes(item);

  const label = text || value || "";
  const type = multiple ? Type.CHECKBOX : Type.RADIO;

  return {
    containerClassName: classNames(styles.container, {
      [styles.container__disabled]: disabled,
      [styles.container__current]: isCurrent,
      [styles.selected]: checked,
      [styles.single]: !multiple,
    }),
    checked,
    menuItemClassName: styles.menuItem,
    label,
    value,
    type,
    prefixIcon,
    suffixIcon,
    multiple,
    tagProps,
    change: useCallback(
      (e: SyntheticEvent<HTMLInputElement, Event>) => {
        const remove = multiple && !e.currentTarget.checked;

        onChange && onChange(item, remove);
      },
      [item, multiple, onChange],
    ),
    click: useCallback(
      (e: React.MouseEvent<HTMLInputElement>) => {
        const remove = e.currentTarget.checked;

        onChange && onChange(item, remove);
      },
      [item, onChange],
    ),
    ...props,
  };
}

export const DropdownMenuItemView = ({
  name,
  label,
  checked,
  value,
  type,
  prefixIcon,
  suffixIcon,
  containerClassName,
  change,
  click,
  menuItemClassName,
  tagProps,
  multiple,
}: DropdownMenuItemViewProps) => (
  <li role="option" className={containerClassName}>
    <label className={menuItemClassName}>
      {prefixIcon}
      <When
        value={multiple}
        then={
          <When
            value={checked}
            then={<CheckBox fontSize={"small"} />}
            otherwise={<CheckBoxOutlineBlank fontSize={"small"} />}
          />
        }
      />

      <input
        type={type}
        name={name}
        onChange={change}
        onClick={click}
        checked={checked}
        value={value}
      />
      <p>{label}</p>
      <When value={tagProps} then={<Tag {...tagProps!} />} />
      {suffixIcon}
    </label>
  </li>
);

export const DropdownMenuItem = selfless(
  DropdownMenuItemView,
  useDropdownMenuItem,
);
export default DropdownMenuItem;
