import React, {
  ReactElement,
  useCallback,
  useContext,
  useState,
  MouseEvent,
} from 'react';

import { StyledDropdownButton, StyledDropdownContent } from './StyledFilters';
import Button from '../../Button';
import Divider from '../../Divider';
import Dropdown from '../../Dropdown';
import FiltersContext from './FiltersContext';
import Icon, { IconName } from '../../Icon';

const getCaretIcon = (open: boolean): IconName => {
  return open === true ? 'arrow-up' : 'arrow-down';
};

const DropdownButton = ({
  text,
  onClick,
  active,
  leftIcon,
  rightIcon,
}: {
  active: boolean;
  leftIcon?: IconName;
  onClick?: (e: MouseEvent) => void;
  rightIcon?: IconName;
  text?: string | ReactElement;
}) => {
  return (
    <StyledDropdownButton onClick={onClick} themeActive={active}>
      {leftIcon !== undefined ? (
        <Icon icon={leftIcon} data-test-id="filter-icon" sx={{ mr: 'small' }} />
      ) : null}
      {text}
      {rightIcon !== undefined ? (
        <Icon icon={rightIcon} data-test-id="filter-icon" />
      ) : null}
    </StyledDropdownButton>
  );
};

const FilterDropdown = ({
  buttonText,
  content,
  dirty,
  icon,
  noCaret,
  onClearButtonClick,
  'data-test-id': dataTestId,
}: {
  buttonText?: string | ReactElement;
  content: ReactElement;
  'data-test-id'?: string;
  dirty: boolean;
  icon?: IconName;
  noCaret?: boolean;
  onClearButtonClick?: () => void;
}) => {
  const { applyButtonProps, clearButtonProps } = useContext(FiltersContext);
  const [open, setOpen] = useState(false);
  const onClose = useCallback(() => setOpen(false), []);
  const shouldRenderApplyButton = applyButtonProps !== undefined;
  const shouldRenderClearButton =
    clearButtonProps !== undefined && onClearButtonClick !== undefined;

  return (
    <Dropdown
      keepContentMounted
      open={open}
      onClose={onClose}
      data-test-id={dataTestId}
      content={
        <StyledDropdownContent>
          {content}
          {(shouldRenderApplyButton || shouldRenderClearButton) && (
            <Divider marginY="medium" />
          )}
          {clearButtonProps !== undefined &&
            onClearButtonClick !== undefined && (
              <Button
                size="small"
                variant="text"
                {...clearButtonProps}
                onClick={onClearButtonClick}
                style={{ float: 'left' }}
              />
            )}
          {applyButtonProps !== undefined && (
            <Button
              size="small"
              {...applyButtonProps}
              onClick={e => {
                onClose();
                applyButtonProps.onClick?.(e);
              }}
              style={{ float: 'right' }}
            />
          )}
        </StyledDropdownContent>
      }
      target={
        <DropdownButton
          text={buttonText}
          leftIcon={icon}
          rightIcon={noCaret === true ? undefined : getCaretIcon(open)}
          onClick={() => setOpen(!open)}
          active={dirty}
        />
      }
    />
  );
};

export default FilterDropdown;
