import React, { useState } from 'react';
import styled from 'styled-components';
import { RoughNotation } from 'react-rough-notation';
import { Flipper } from 'react-flip-toolkit';
import PropTypes from 'prop-types';
import Icon from '../../Icon';
import DropdownContainer from './dropDownContainer';
import generateNavBar from './dropDown';

const menuColors = [
  '#fac6a1',
  '#a9ddd7',
  '#afc2e7',
  '#f7daa6',
  '#f9a6a2',
  '#f8cfb6',
  '#fac6a1',
  '#a9ddd7',
  '#afc2e7',
  '#f7daa6',
  '#f9a6a2',
  '#f8cfb6'
];

const NavItemIconDropDown = styled.span`
  width: 24px;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: transform 0.3s ease-in-out;
  ${props =>
    props.show &&
    `
		transform: rotate(180deg);
	`}
`;

const NavItemButtonContent = styled.span`
  display: flex;
  flex-direction: row;
  flex-wrap: no-wrap;
  height: 100%;
  -webkit-box-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  align-items: center;
`;

const NavItemButtonContainer = styled.span`
  display: flex;
  height: 100%;
  -webkit-box-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  align-items: center;
`;

const NavItemButton = styled.div`
  font-weight: 400;

  display: flex;
  align-items: center;
  background: transparent;
  border: 0;
  font-weight: 400;
  font-family: inherit;
  font-size: 17px;
  padding: 0 20px;
  height: 100%;
  color: ${props => props.theme.colors.secondary};
  justify-content: center;
  white-space: nowrap;
  transition: opacity 250ms;
  cursor: pointer;
  position: relative;
  z-index: 2;

  &:focus {
    outline: none;
    color: ${props => props.theme.colors.grey.v500};
  }

  &:visited {
    color: ${props => props.theme.colors.secondary};
  }

  &:active {
    outline: none;
    color: ${props => props.theme.colors.secondary};
  }

  span {
    display: flex;
    height: 100%;
    justify-content: center;
    align-items: center;
  }

  &:link {
    text-decoration: none;
  }
  &:visited {
    text-decoration: none;
  }
  &:hover {
    text-decoration: none;
  }
  &:active {
    text-decoration: none;
  }
`;

const NavItem = styled.li`
  position: relative;
  margin: 0px;
  font-family: inherit;
`;

const Main = styled.div`
  display: none;
  font-family: ${props => props.theme.fonts.text};

  @media (min-width: ${props => props.theme.breakpoints.xlarge}px) {
    display: flex;
    justify-content: center;
  }
`;

const Root = styled.ul`
  display: flex;
  -webkit-box-pack: center;
  justify-content: center;
  list-style: none;
  margin: 0px;
  padding: 0px;
  font-family: inherit;
`;

const DropdownSlot = styled.div`
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  perspective: 1500px;
  z-index: 10;
`;

const Menu = ({ menu, test, id }) => {
  let navbar = generateNavBar(menu, test);
  let [hover, setHover] = useState(null);
  const [activeIndices, setActiveIndices] = React.useState([]);
  const [animatingOut, setAnimatingOut] = React.useState(false);
  const [animatingOutTimeout, setAnimatingOutTimeout] = React.useState(null);

  const resetDropdownState = i => {
    setActiveIndices(typeof i === 'number' ? [i] : []);
    setAnimatingOut(false);
    setAnimatingOutTimeout(null);
  };

  const onMouseEnter = i => {
    setHover(i);
    if (animatingOutTimeout) {
      clearTimeout(animatingOutTimeout);
      resetDropdownState(i);
      return;
    }
    if (activeIndices[activeIndices.length - 1] === i) {
      return;
    }

    // If there is no dropdown for the item
    if (!navbar[i]?.dropdown) {
      onMouseLeave(i);
      return;
    }

    setActiveIndices(prevState => prevState.concat(i));
    setAnimatingOut(false);
  };

  const onMouseLeave = i => {
    setHover(i ? i : null);
    setAnimatingOut(true);
    const timer = setTimeout(resetDropdownState, duration);
    setAnimatingOutTimeout(timer);
  };

  let CurrentDropdown;
  let PrevDropdown;
  let direction;

  const currentIndex = activeIndices[activeIndices.length - 1];
  const prevIndex = activeIndices.length > 1 && activeIndices[activeIndices.length - 2];

  // current
  if (typeof currentIndex === 'number') {
    CurrentDropdown = navbar[currentIndex].dropdown;
  }
  // previous
  if (typeof prevIndex === 'number') {
    PrevDropdown = navbar[prevIndex].dropdown;
    direction = currentIndex > prevIndex ? 'right' : 'left';
  }

  const showDropdown = !!CurrentDropdown;
  const duration = 300;

  return (
    <Main id={id ? id : 'main_menu'}>
      <Flipper flipKey={currentIndex} spring={duration === 300 ? 'noWobble' : { stiffness: 10, damping: 10 }}>
        <Root onMouseLeave={onMouseLeave}>
          {menu.map((elem, index) => {
            const roughNotationProps = {
              show: index === hover && (elem?.noRoughAnimation ? !elem?.noRoughAnimation : true),
              type: 'underline',
              padding: elem?.submenu ? -25 : 5,
              iterations: 1,
              strokeWidth: 3,
              color: menuColors[index],
              animationDuration: 300
            };

            return (
              <NavItem index={index} key={index}>
                <NavItemButton
                  id={elem.name}
                  onMouseEnter={() => {
                    onMouseEnter(index);
                  }}
                  href={elem?.submenu?.length > 0 ? '' : elem?.link}
                  as={elem?.submenu?.length > 0 ? 'button' : 'a'}
                >
                  <NavItemButtonContainer>
                    <RoughNotation {...roughNotationProps}>
                      <NavItemButtonContent>
                        {elem.name}
                        {elem?.submenu ? (
                          <NavItemIconDropDown
                            show={index === hover && (elem?.noAnimatedIcon ? !elem?.noAnimatedIcon : true)}
                            name={test ? elem.icon : 'ArrowDown'}
                          >
                            <Icon iconSize={24} iconWidth={15} name={test ? elem.icon : 'ArrowDown'} />
                          </NavItemIconDropDown>
                        ) : null}
                      </NavItemButtonContent>
                    </RoughNotation>
                  </NavItemButtonContainer>
                </NavItemButton>
                {currentIndex === index && showDropdown ? (
                  <DropdownSlot>
                    <DropdownContainer direction={direction} animatingOut={animatingOut} duration={duration}>
                      <CurrentDropdown />
                      {PrevDropdown && <PrevDropdown />}
                    </DropdownContainer>
                  </DropdownSlot>
                ) : null}
              </NavItem>
            );
          })}
        </Root>
      </Flipper>
    </Main>
  );
};

Menu.propTypes = {
  menu: PropTypes.array.isRequired,
  test: PropTypes.bool,
  id: PropTypes.string
};

export default Menu;
