import { useState } from 'react';
import { useFormContext } from 'react-hook-form';

import {
  IconChevronDown,
  IconExclamationCircle,
  IconMinus,
} from '@material-hu/icons/tabler';
import ClickAwayListener from '@material-hu/mui/ClickAwayListener';
import Grid from '@material-hu/mui/Grid';
import IconButton from '@material-hu/mui/IconButton/IconButton';
import Paper from '@material-hu/mui/Paper';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';

import { CATEGORY_ICONS } from '../../constants';
import { type CategoryIcon } from '../../types';
import { transformCategoryIconsToOptions } from '../../utils';

const MENU_HEIGHT = '258px';
const options = transformCategoryIconsToOptions();

type Props = {
  error?: boolean;
};

const SelectIcon = ({ error }: Props) => {
  const theme = useTheme();
  const [open, setOpen] = useState(false);

  const { setValue, watch } = useFormContext();

  const icon: CategoryIcon = watch('icon');

  const handleSelect = (newIcon: CategoryIcon) => {
    setValue('icon', newIcon);
    setOpen(false);
  };

  const SelectedIcon = icon && CATEGORY_ICONS[icon]?.Icon;

  const handleToggle = () => setOpen(prev => !prev);

  const getBorderColor = () => {
    if (error && !icon) return theme.palette.new.border.states.error;
    if (open) return theme.palette.new.border.neutral.brand;
    return theme.palette.new.border.neutral.default;
  };

  return (
    <ClickAwayListener onClickAway={() => setOpen(false)}>
      <Stack sx={{ minWidth: '88px' }}>
        <Stack sx={{ position: 'relative', height: '55px' }}>
          <Stack
            onClick={handleToggle}
            sx={{
              cursor: 'pointer',
              flexDirection: 'row',
              alignItems: 'center',
              justifyContent: 'space-between',
              p: 1.6,
              borderRadius: 1,
              height: 1,
              border: `1px solid ${getBorderColor()}`,
            }}
          >
            {!icon && (
              <IconMinus
                size={24}
                color={theme.palette.new.text.neutral.default}
              />
            )}
            {SelectedIcon && <SelectedIcon size={24} />}
            <IconChevronDown
              size={16}
              style={{
                color: theme.palette.new.text.neutral.default,
                transform: open ? 'rotate(180deg)' : 'rotate(0deg)',
                transition: 'transform 0.1s ease',
              }}
            />
          </Stack>
          <Grid
            container
            component={Paper}
            elevation={7}
            sx={{
              width: 'fit-content',
              display: 'grid',
              gridTemplateColumns: 'repeat(6, 1fr)',
              gap: 0.5,
              p: 2,
              position: 'absolute',
              left: '0px',
              bottom: `-${MENU_HEIGHT}`,
              borderRadius: 1,
              backgroundColor: ({ palette }) =>
                palette.new.background.elements.grey,
              zIndex: 1,
              opacity: open ? 1 : 0,
              transform: open ? 'translateY(0)' : `translateY(-20px)`,
              visibility: open ? 'visible' : 'hidden',
              transition:
                'opacity 0.3s ease, transform 0.3s ease, visibility 0.3s ease',
            }}
          >
            {options.map(option => (
              <Grid
                key={option.value}
                item
                sx={{ p: '0px !important' }}
                onClick={() => handleSelect(option.value)}
              >
                <IconButton
                  variant={
                    icon === option.value ? 'tertiary-filled' : 'tertiary'
                  }
                >
                  <option.icon
                    size={24}
                    color={theme.palette.new.text.neutral.default}
                  />
                </IconButton>
              </Grid>
            ))}
          </Grid>
        </Stack>
        {error && !icon && (
          <IconExclamationCircle
            size="1rem"
            style={{
              marginTop: '8px',
              color: theme.palette.new.text.feedback.error,
            }}
          />
        )}
      </Stack>
    </ClickAwayListener>
  );
};

export default SelectIcon;
