import { Box, Popper, ClickAwayListener, Autocomplete, autocompleteClasses, InputBase, ButtonBase, alpha } from '@mui/material';
import { Fragment, useMemo, useState, createElement as _createElement } from 'react';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import PropTypes from 'prop-types';
import LabelIcon from '@mui/icons-material/LocalOfferOutlined';
import { useSessionContext } from '../../../contexts/session';
import LabelChip from '../chip';
import { useLabels } from '../context/context';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
function PopperComponent({
  ...other
}) {
  return /*#__PURE__*/_jsx(Box, {
    ...other,
    sx: theme => ({
      [`& .${autocompleteClasses.paper}`]: {
        width: 360,
        boxShadow: 'none',
        margin: 0,
        color: 'inherit',
        fontSize: 13
      },
      [`& .${autocompleteClasses.listbox}`]: {
        bgcolor: theme.palette.background.paper,
        padding: 1,
        [`& .${autocompleteClasses.option}`]: {
          minHeight: 'auto'
        }
      },
      [`&.${autocompleteClasses.popperDisablePortal}`]: {
        position: 'relative'
      }
    })
  });
}
PopperComponent.propTypes = {};
function LabelPicker({
  value = [],
  onChange = undefined,
  noLabelsText = undefined,
  buttonSx = undefined,
  actions = undefined,
  trigger = undefined,
  multiple = true,
  updateImmediately = true,
  excludes = [],
  disabled = false,
  enableAccessControl = true,
  disablePortal = false,
  disableCreate = false
}) {
  const {
    t,
    locale
  } = useLocaleContext();
  const {
    session
  } = useSessionContext();
  const isAdmin = ['owner', 'admin'].includes(session?.user?.role);
  const {
    flattenedLabels: labels,
    getLabelsByIds,
    loading,
    createLabel,
    recentLabels,
    addRecentLabel
  } = useLabels();
  const [anchorEl, setAnchorEl] = useState(null);
  const [inputValue, setInputValue] = useState('');
  const selectedLabelIds = value;
  const selectedLabels = useMemo(() => getLabelsByIds(selectedLabelIds), [getLabelsByIds, selectedLabelIds]);
  const exists = useMemo(() => labels.some(x => x.data.getName(locale)?.toLowerCase() === inputValue.toLowerCase()), [inputValue, labels, locale]);
  const filteredLabels = useMemo(() => {
    const excludesSet = new Set(excludes);
    return labels.filter(x => !excludesSet.has(x.data.id));
  }, [labels, excludes]);
  const initialRecentLabels = useMemo(() => {
    const excludesSet = new Set(excludes);
    return recentLabels.filter(x => !excludesSet.has(x));
  }, [recentLabels, excludes]);
  const open = Boolean(anchorEl);
  const id = open ? 'label-picker' : undefined;
  const getSelectedSx = selected => selected ? {
    bgcolor: theme => `${theme.palette.primary.main} !important`,
    color: theme => `${theme.palette.primary.contrastText} !important`,
    WebkitTextFillColor: theme => `${theme.palette.primary.contrastText} !important`
  } : undefined;
  const isLabelPermitted = () => !enableAccessControl || isAdmin;
  const handleClick = event => {
    if (disabled) return;
    event.preventDefault();
    setAnchorEl(event.currentTarget);
  };
  const handleClose = () => {
    if (!updateImmediately) onChange?.(selectedLabelIds);
    setInputValue('');
    anchorEl?.focus();
    setAnchorEl(null);
  };
  const handleCreate = async () => {
    const {
      id: newLabelId
    } = await createLabel(inputValue);
    if (!multiple) onChange?.([newLabelId]);else if (updateImmediately) onChange([...selectedLabelIds, newLabelId]);
  };
  const handleLabelSelectionChange = newValue => {
    if (!multiple) {
      onChange?.(newValue.length ? [newValue[newValue.length - 1]] : []);
      setAnchorEl(null);
    } else if (updateImmediately) onChange(newValue);
  };
  if (loading) return null;
  const renderRecentLabels = () => {
    const recentLabelNodes = getLabelsByIds(initialRecentLabels).filter(isLabelPermitted);
    if (!recentLabelNodes?.length) return null;
    return /*#__PURE__*/_jsxs(Box, {
      component: "li",
      children: [/*#__PURE__*/_jsx(Box, {
        sx: {
          mb: 0.5,
          fontSize: 12,
          fontWeight: 'medium'
        },
        children: t('label.recently')
      }), /*#__PURE__*/_jsx(Box, {
        sx: {
          display: 'flex',
          flexWrap: 'wrap',
          gap: 0.75,
          mb: 2
        },
        children: recentLabelNodes.map(x => {
          const labelId = x.data.id;
          const selected = value?.includes(labelId);
          return /*#__PURE__*/_jsx(LabelChip, {
            label: x.data,
            onClick: () => handleLabelSelectionChange(selected ? selectedLabelIds.filter(y => y !== labelId) : [...selectedLabelIds, labelId]),
            sx: {
              height: 24,
              lineHeight: '24px',
              '.MuiChip-label': {
                maxHeight: 24
              },
              ...getSelectedSx(selected)
            }
          }, labelId);
        })
      })]
    });
  };
  const renderGroup = params => /*#__PURE__*/_jsxs(Box, {
    component: "li",
    children: [/*#__PURE__*/_jsx(Box, {
      sx: {
        mb: 0.5,
        fontSize: 12,
        fontWeight: 'medium'
      },
      children: t('label.title')
    }), /*#__PURE__*/_jsx(Box, {
      component: "ul",
      sx: {
        display: 'flex',
        flexWrap: 'wrap',
        gap: 0.75,
        p: 0
      },
      children: params.children
    })]
  });
  const renderAutocomplete = () => /*#__PURE__*/_jsx(Autocomplete, {
    open: true,
    multiple: true,
    inputValue: inputValue,
    onInputChange: (e, newValue, reason) => {
      if (reason === 'reset' || reason === 'blur') return;
      setInputValue(newValue);
    },
    onClose: (e, reason) => reason === 'escape' && handleClose(),
    value: selectedLabels,
    onChange: (event, newValue, reason) => {
      event.preventDefault();
      if (event.type === 'keydown' && event.key === 'Backspace' && reason === 'removeOption') return;
      if (reason === 'selectOption') addRecentLabel(newValue[newValue.length - 1].data.id);
      handleLabelSelectionChange(newValue.map(x => x.data.id));
    },
    disableCloseOnSelect: true,
    renderTags: () => null,
    noOptionsText: noLabelsText || t('label.noLabels'),
    groupBy: () => 'x',
    renderOption: (props, option, {
      selected
    }) => {
      if (!isLabelPermitted(option)) return null;
      const label = option.data;
      return /*#__PURE__*/_createElement(Box, {
        component: "li",
        ...props,
        key: label.id,
        sx: {
          '&.MuiAutocomplete-option': {
            p: '0 !important'
          }
        }
      }, /*#__PURE__*/_jsx(LabelChip, {
        label: label,
        sx: {
          height: 24,
          lineHeight: '24px',
          '.MuiChip-label': {
            maxHeight: 24
          },
          ...getSelectedSx(selected)
        }
      }));
    },
    renderGroup: params => /*#__PURE__*/_jsxs(Fragment, {
      children: [renderRecentLabels(), renderGroup(params)]
    }, params.key),
    options: filteredLabels,
    getOptionLabel: option => option.data.getName(locale),
    renderInput: params => /*#__PURE__*/_jsx(Box, {
      component: InputBase,
      ref: params.InputProps.ref,
      inputProps: params.inputProps,
      autoFocus: true,
      placeholder: t('label.filter'),
      sx: theme => ({
        padding: 1,
        width: '100%',
        bgcolor: 'background.paper',
        '& input': {
          borderRadius: 1,
          backgroundColor: 'background.paper',
          padding: 1,
          transition: theme.transitions.create(['border-color', 'box-shadow']),
          border: `1px solid ${theme.palette.divider}`,
          fontSize: 14,
          '&:focus': {
            boxShadow: `0px 0px 0px 3px ${alpha(theme.palette.primary.light, 0.4)}`,
            borderColor: theme.palette.primary.light
          }
        }
      })
    }),
    slots: {
      popper: PopperComponent
    }
  });
  const renderActions = () => /*#__PURE__*/_jsxs(Box, {
    onClick: e => e.stopPropagation(),
    children: [isAdmin && inputValue && !exists && /*#__PURE__*/_jsx(Box, {
      sx: {
        display: 'flex',
        alignItems: 'center',
        gap: 1,
        width: '100%',
        height: 36,
        px: 2,
        borderTop: '1px solid',
        borderColor: 'divider',
        fontSize: 14,
        color: 'grey.600',
        cursor: 'pointer'
      },
      onClick: handleCreate,
      children: t('label.createNewLabel', {
        name: inputValue
      })
    }), actions]
  });
  return /*#__PURE__*/_jsxs(_Fragment, {
    children: [/*#__PURE__*/_jsx(Box, {
      onClick: handleClick,
      sx: {
        display: 'flex',
        alignItems: 'center'
      },
      children: trigger || /*#__PURE__*/_jsx(ButtonBase, {
        disableRipple: true,
        "aria-describedby": id,
        className: "label-picker-trigger",
        sx: [theme => ({
          width: '100%',
          fontSize: 13,
          color: theme.palette.mode === 'light' ? '#586069' : '#8b949e',
          fontWeight: 600,
          '&:hover': {
            color: theme.palette.mode === 'light' ? 'primary.main' : '#58a6ff'
          },
          '& svg': {
            width: 22,
            height: 22
          }
        }), ...(Array.isArray(buttonSx) ? buttonSx : [buttonSx])],
        children: /*#__PURE__*/_jsx(LabelIcon, {
          style: {
            fontSize: 14
          }
        })
      })
    }), /*#__PURE__*/_jsx(Popper, {
      id: id,
      open: open,
      anchorEl: anchorEl,
      placement: "bottom-start",
      disablePortal: disablePortal,
      sx: theme => ({
        border: `1px solid ${theme.palette.divider}`,
        boxShadow: `0 8px 24px ${theme.palette.mode === 'light' ? 'rgba(149, 157, 165, 0.2)' : 'rgb(1, 4, 9)'}`,
        borderRadius: 1,
        width: 360,
        overflow: 'hidden',
        zIndex: theme.zIndex.modal,
        fontSize: 13,
        color: 'text.secondary',
        backgroundColor: 'background.paper'
      }),
      children: /*#__PURE__*/_jsx(ClickAwayListener, {
        onClickAway: handleClose,
        children: /*#__PURE__*/_jsxs(Box, {
          onClick: e => e.preventDefault(),
          children: [renderAutocomplete(), !disableCreate && renderActions()]
        })
      })
    })]
  });
}
LabelPicker.propTypes = {
  value: PropTypes.array,
  onChange: PropTypes.func,
  noLabelsText: PropTypes.string,
  buttonSx: PropTypes.array,
  actions: PropTypes.array,
  trigger: PropTypes.element,
  multiple: PropTypes.bool,
  updateImmediately: PropTypes.bool,
  excludes: PropTypes.array,
  disabled: PropTypes.bool,
  enableAccessControl: PropTypes.bool,
  disablePortal: PropTypes.bool,
  labels: PropTypes.array,
  disableCreate: PropTypes.bool
};
export default LabelPicker;