/* eslint-disable react/jsx-no-bind */
import React, { useState, use, useRef, useMemo } from 'react';
import {
  Button,
  Typography,
  IconButton,
  Popper,
  MenuItem,
  MenuList,
  Box,
  ClickAwayListener,
  Paper,
} from '@mui/material';
import { Icon as IconifyIcon } from '@iconify/react';
import CheckIcon from '@iconify-icons/material-symbols/check';
import LanguageIcon from 'iconify-icons-material-symbols-400/language';

import { LocaleContext } from './context';
import { styled } from '../Theme';
import type { Locale } from '../type';
import { mergeSx } from '../Util/style';

export interface LocaleSelectorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
  showText?: true | false;
  popperProps?: React.HTMLAttributes<HTMLDivElement>;
  popperType?: 'hover' | 'click';
  icon?: React.ComponentType<any>;
  size?: number;
  onChange?: (locale: Locale) => void;
}

export default function LocaleSelector({ ...props }: LocaleSelectorProps) {
  const { showText = true, popperProps = {}, popperType = 'click', icon: Icon, size = 24, ...rest } = props;
  const { locale, changeLocale, languages } = use(LocaleContext);
  const anchorEl = useRef<HTMLButtonElement>(null);
  const [open, setOpen] = useState(false);

  const onSelect = (newLocale: Locale) => {
    changeLocale(newLocale);
    setOpen(false);
    if (typeof props.onChange === 'function') {
      props.onChange(newLocale);
    }
  };

  const onClose = (e: MouseEvent | TouchEvent) => {
    if (anchorEl.current?.contains(e.target as Node)) {
      return;
    }
    setOpen(false);
  };

  const ButtonComponent: typeof Button = showText ? Button : IconButton;

  const handleEventProps =
    popperType === 'hover'
      ? {
          onMouseEnter: () => {
            setOpen(true);
          },
          onMouseLeave: () => {
            setOpen(false);
          },
        }
      : {
          onClick: () => {
            setOpen(!open);
          },
        };

  const renderIcon = useMemo(() => {
    if (Icon) {
      return <Icon />;
    }

    return <IconifyIcon icon={LanguageIcon} fontSize={size} style={{ transform: 'scale(1.10)' }} />;
  }, [Icon, size]);

  return (
    // @ts-ignore
    <Wrapper {...rest} {...handleEventProps}>
      <ButtonComponent ref={anchorEl} className="trigger" role="button" aria-label="Locale selector button">
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
          }}>
          {renderIcon}

          {showText ? (
            <Typography component="strong" className="trigger-text">
              {languages.find((x) => x.code === locale)?.name}
            </Typography>
          ) : (
            ''
          )}
        </Box>
      </ButtonComponent>
      <Popper
        open={open}
        anchorEl={anchorEl.current}
        {...popperProps}
        // @ts-ignore
        sx={mergeSx(
          // @ts-ignore
          { zIndex: (_theme) => _theme.zIndex.tooltip + 10 },
          // @ts-ignore
          popperProps?.sx
        )}>
        <Paper
          variant="outlined"
          className="locales"
          sx={{
            borderRadius: 1,
          }}>
          <ClickAwayListener onClickAway={onClose}>
            <MenuList>
              {languages.map(({ code, name }) => {
                return (
                  <MenuItem
                    key={code}
                    className="locale-item"
                    onClick={() => onSelect(code)}
                    sx={{
                      fontSize: 16,
                      fontStyle: 'normal',
                      fontStretch: 'normal',
                      lineHeight: 'normal',
                      letterSpacing: '2px',
                      textAlign: 'center',
                      color: 'text.primary',
                      cursor: 'pointer',
                      display: 'flex',
                      padding: '16px',
                      alignItems: 'center',
                    }}>
                    <Box
                      component={IconifyIcon}
                      icon={CheckIcon}
                      className={code === locale ? 'check-icon check-icon-visible' : 'check-icon'}
                      sx={{
                        marginRight: 1,
                        visibility: code === locale ? 'visible' : 'hidden',
                      }}
                    />
                    {name}
                  </MenuItem>
                );
              })}
            </MenuList>
          </ClickAwayListener>
        </Paper>
      </Popper>
    </Wrapper>
  );
}

const Wrapper = styled(Box)`
  display: inline-block;

  .trigger {
    display: flex;
    flex-direction: column;
    justify-content: center;
    font-size: 14px;
    white-space: nowrap;

    .trigger-text {
      margin-left: 5px;
      font-size: 14px;
      color: ${({ theme }) => theme.palette.text.primary};
    }
  }
`;
