/* eslint-disable @next/next/no-img-element */
import Link from 'next/link';
import styles from './Header.module.scss';
import { Image as ImageI, Link as LinkI } from '../../models/common';
import { useRouter } from 'next/dist/client/router';
import DotLink from './DotLink';
import { motion } from 'framer-motion';
import { useEffect, useState } from 'react';
import { ThemeOverflow } from '../../redux/reducers/themeReducer/model';
import { useMediaQuery } from 'react-responsive';
import LanguageSelector from '../LanguageSelector';
import NextImage from 'next/legacy/image';

export enum HeaderLinkType {
  LINK = 'link',
  EXPANDABLE_DOT = 'expandable_dot',
}

export interface HeaderLink extends LinkI {
  type?: HeaderLinkType | null;
}

type Props = {
  image: ImageI;
  links: HeaderLink[];
};

const variants = {
  hover: {
    width: '100%',
    background: '#2766c4'
  },
  initial: {
    width: '60%',
    background: '#2766c4'
  },
  initialBar1And2: {
    width: '100%',
    background: '#2766c4'
  },
  activeBar1: {
    width: '60%',
    rotate: '45deg',
    background: '#fff',
    y: '0.5px',
    x: '4px'
  },
  activeBar2: {
    rotate: '0deg',
    background: '#fff',
    width: '140%'
  },
  activeBar3: {
    width: '60%',
    rotate: '-45deg',
    background: '#fff',
    y: '-0.5px',
    x: '4px'
  }
};

const menuVariant = {
  visible: {
    y: '0%',
    transition: {
      duration: 0.3,
      when: 'beforeChildren',
      staggerChildren: 0.054
    },
    transitionEnd: {
      transform: `unset`
    }
  },
  hidden: {
    y: '-100%',
    transition: {
      duration: 0.3,
      staggerChildren: 0.054,
      staggerDirection: -1,
      when: 'afterChildren'
    },
    transitionEnd: {
      transform: `unset`
    }
  }
};

const linksVariants = {
  visible: {
    y: '0%',
    opacity: 1,
    transition: {
      duration: 0.25
    }
  },
  hidden: {
    y: '200%',
    opacity: 0,
    transition: {
      duration: 0.25
    }
  }
};

const Header = (props: Props): JSX.Element => {
  const router = useRouter();
  const { image, links } = props;
  const menuLinks = links.filter(
    (link) => link.type !== HeaderLinkType.EXPANDABLE_DOT
  );
  const dotLink = links.find(
    (link) => link.type === HeaderLinkType.EXPANDABLE_DOT
  );
  const activeClassName = (url: string) => {
    return url === router.asPath ||
    router.asPath === `/${router.locale}` ||
    url === `/${router.locale}${router.asPath}` ||
    (url === `/${router.locale}` && router.asPath === `/`)
      ? styles.activeHeader
      : '';
  };
  const [isMenuVisible, setIsMenuVisible] = useState(false);
  const [isMouseOver, setIsMouseOver] = useState(false);
  const isDesktop = useMediaQuery({ query: '(min-width: 900px)' });
  const [isAnim, setIsAnim] = useState(false);

  const toggleMenu = async (delay?: boolean): Promise<void> => {
    const overflow = !isMenuVisible
      ? ThemeOverflow.HIDDEN
      : ThemeOverflow.VISIBLE;
    if (delay) await new Promise((resolve) => setTimeout(resolve, 1000));
    setIsMenuVisible(!isMenuVisible);
    document.body.style.overflow =
      overflow === ThemeOverflow.HIDDEN ? 'hidden' : '';
  };

  const resize = () => {
    if (isDesktop) {
      setIsMenuVisible(false);
      document.body.style.overflow = '';
    }
  };

  useEffect(() => {
    window.addEventListener('resize', resize);
    return () => {
      window.removeEventListener('resize', resize);
    };
  }, []);

  return (
    <header className={styles.header}>
      <div className={styles.container}>
        <div className={styles.logo}>
          <Link href={'/'} legacyBehavior={true}>
            <a aria-label='company icon' className={`${activeClassName('/')}`}>
              {image.src && <NextImage src={image.src} width={90} height={40} alt={image?.alt || ''} />}
            </a>
          </Link>
        </div>
        <div className={styles.topMenus}>
          {menuLinks?.map((link, id) => {
            return link?.type === HeaderLinkType.EXPANDABLE_DOT ? (
              <DotLink
                key={id}
                url={link.url || ''}
                className={`${activeClassName(link.url)}`}
              >
                {link.label}
              </DotLink>
            ) : (
              <Link
                href={link.url}
                key={id}
                passHref={link?.type ? true : false}
                locale={false}
                legacyBehavior={true}
              >
                <a
                  className={`${activeClassName(link.url)}`}
                  data-label={link.label}
                >
                  <span>{link.label}</span>
                </a>
              </Link>
            );
          })}
          <LanguageSelector />
          {dotLink && (
            <DotLink
              url={dotLink.url || ''}
              className={`${activeClassName(dotLink.url)}`}
            >
              {dotLink.label}
            </DotLink>
          )}
        </div>
        <motion.button
          type='button'
          className={styles.hamb}
          aria-label={'menu'}
          onMouseEnter={() => {
            setIsMouseOver(true);
          }}
          onMouseLeave={() => {
            setIsMouseOver(false);
          }}
          onClick={async () => {
            if (isAnim) return;
            setIsAnim(true);
            await toggleMenu();
            setIsMouseOver(false);
          }}
        >
          <motion.span
            animate={isMenuVisible ? 'activeBar1' : 'initialBar1And2'}
            variants={variants}
          />
          <motion.span
            variants={variants}
            animate={isMenuVisible ? 'activeBar2' : 'initialBar1And2'}
          />
          <motion.span
            variants={variants}
            animate={
              isMenuVisible ? 'activeBar3' : !isMouseOver ? 'initial' : 'hover'
            }
          />
        </motion.button>
        <motion.div
          className={styles.menuMobile}
          variants={menuVariant}
          animate={isMenuVisible ? 'visible' : 'hidden'}
          initial={false}
          onAnimationComplete={() => {
            setIsAnim(false);
          }}
          transformTemplate={({ y }) =>
            y === 'unset' || y === '0%' ? 'unset' : `translateY(${y})`
          }
        >
          <div className={styles.menuMobileContainer}>
            <div className={styles.menuMobileLanguages}>
              <LanguageSelector />
            </div>
            {links?.map((link, id) => (
              <motion.div key={id} variants={linksVariants}>
                <Link
                  href={link.url || ''}
                  passHref={link?.type ? true : false}
                  legacyBehavior={true}
                >
                  <a
                    className={`${activeClassName(link.url)}`}
                    onClick={() => toggleMenu(true)}
                  >
                    {link.label}
                  </a>
                </Link>
              </motion.div>
            ))}
          </div>
        </motion.div>
      </div>
    </header>
  );
};

export default Header;
