import { useEffect, useState } from 'react';

import { useLocale, useTranslations } from 'next-intl';
import Image from 'next/image';

import { motion, useReducedMotion } from 'framer-motion';
import { FaChevronRight } from 'react-icons/fa';
import { IoChevronBack } from 'react-icons/io5';
import { useMediaQuery } from 'react-responsive';

import { useDisableScroll } from '@/hooks/useDisableScroll';
import { metaAttributes110 } from '@/utils/filterUtils';

import { mainMenuItems } from '@/config/menuItems';
import { MainMenuElement } from '@/config/menuItems';
import { programsMenuItems } from '@/config/programsMenuItems';
import { usePathname } from '@/i18n/navigation';
import { Link } from '@/i18n/navigation';

import LangSelector from './LangSelector';
import SearchBar from './SearchBar';

interface MobileMenuProps {
  isOpen: boolean;
  closeMenu: () => void;
}

const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, closeMenu }) => {
  useDisableScroll(isOpen);

  const pathname = usePathname();
  const prefersReducedMotion = useReducedMotion();
  const [radius, setRadius] = useState<number>(1200);
  const isMidScreen = useMediaQuery({ minWidth: 1024 });
  const [activeItem, setActiveItem] = useState<MainMenuElement | null>(null);
  const tMenu = useTranslations('navigation.menu');
  const tPrograms = useTranslations('navigation.programsDropdown');
  const tCategory = useTranslations('navigation.categoryDropdown');
  const tCategories = useTranslations('categories');
  const listVariants = {
    hidden: { opacity: 0, y: 6 },
    show: {
      opacity: 1,
      y: 0,
      transition: { staggerChildren: 0.04, delayChildren: 0.05 },
    },
  };
  const itemVariants = {
    hidden: { opacity: 0, y: 4 },
    show: { opacity: 1, y: 0 },
  };

  useEffect(() => {
    const updateRadius = () => setRadius(Math.hypot(window.innerWidth, window.innerHeight));
    updateRadius();
    window.addEventListener('resize', updateRadius);
    window.addEventListener('orientationchange', updateRadius);
    return () => {
      window.removeEventListener('resize', updateRadius);
      window.removeEventListener('orientationchange', updateRadius);
    };
  }, []);

  useEffect(() => {
    const el = document.getElementById('back-to-top-button');
    if (!el) return;
    if (isOpen) el.setAttribute('hidden', 'true');
    else el.removeAttribute('hidden');
  }, [isOpen]);

  // close on 'esc' press
  useEffect(() => {
    if (!isOpen) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') closeMenu();
    };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [isOpen, closeMenu]);

  // close on route change
  useEffect(() => {
    if (isOpen) closeMenu();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pathname]);

  // close on resize if > desktop-width
  useEffect(() => {
    if (isMidScreen && isOpen) closeMenu();
  }, [isMidScreen, isOpen, closeMenu]);

  useEffect(() => {
    if (!isOpen) setActiveItem(null);
  }, [isOpen]);

  const locale = useLocale();
  const itemsForLocale = mainMenuItems.filter(
    (item) => !item.visibleLocales || item.visibleLocales.includes(locale)
  );
  const visibleProgramsItems = programsMenuItems.filter(
    (item) => !item.visibleLocales || item.visibleLocales.includes(locale)
  );
  const backLabel = locale === 'en' ? 'Back' : 'Vissza';

  const handleClose = () => {
    setActiveItem(null);
    closeMenu();
  };

  return (
    <motion.div
      role="dialog"
      aria-modal="true"
      className="fixed left-0 right-0 top-[var(--header-h)] bottom-0 z-[1000] bg-white px-site py-4 overflow-hidden flex flex-col"
      initial={false}
      style={{ willChange: 'clip-path' }}
      animate={isOpen ? 'open' : 'closed'}
      custom={radius}
      variants={{
        open: (r: number) => ({
          clipPath: `circle(${r}px at 95% 0)`,
          display: 'flex',
          transition: prefersReducedMotion
            ? { duration: 0 }
            : { type: 'spring', stiffness: 100, damping: 18 },
        }),
        closed: {
          clipPath: 'circle(0px at 95% 0)',
          transitionEnd: { display: 'none' },
          transition: prefersReducedMotion
            ? { duration: 0 }
            : { type: 'spring', stiffness: 500, damping: 40 },
        },
      }}
    >
      <div className="flex flex-col gap-4 items-center w-full h-full min-h-0">
        <div className="flex w-full gap-2">
          <SearchBar
            isMobile={true}
            closeMenu={closeMenu}
            inputClassName="text-xl border border-[#151720]/20"
          />
          <LangSelector />
        </div>
        <nav className="flex flex-col w-full overflow-y-auto overflow-x-hidden min-h-0 scroll-smooth">
          <motion.div
            className="flex w-full"
            animate={{ x: activeItem ? '-100%' : '0%' }}
            transition={
              prefersReducedMotion ? { duration: 0 } : { duration: 0.22, ease: 'easeInOut' }
            }
          >
            <div className="w-full flex-shrink-0">
              <ul className="w-full divide-y divide-black/10">
                {itemsForLocale.map((item) => {
                  const hasChildren = item.hasCategoryDropdown || item.hasProgramsDropdown;
                  if (!hasChildren) {
                    return (
                      <li key={item.label}>
                        <Link
                          href={item.to}
                          className="flex items-center justify-between py-4 text-[#151720]/80 font-semibold uppercase tracking-[0.08em]"
                          onClick={handleClose}
                        >
                          {tMenu(item.labelKey)}
                        </Link>
                      </li>
                    );
                  }

                  return (
                    <li key={item.label}>
                      <button
                        type="button"
                        className="flex w-full items-center justify-between py-4 text-[#151720]/80 font-semibold uppercase tracking-[0.08em]"
                        onClick={() => setActiveItem(item)}
                      >
                        <span>{tMenu(item.labelKey)}</span>
                        <FaChevronRight className="text-[#151720]/60" />
                      </button>
                    </li>
                  );
                })}
              </ul>
            </div>

            <div className="w-full flex-shrink-0">
              {activeItem && (
                <div className="w-full">
                  <button
                    type="button"
                    className="flex items-center gap-2 py-3 text-[#151720]/70 font-semibold uppercase tracking-[0.08em] w-full"
                    onClick={() => setActiveItem(null)}
                  >
                    <IoChevronBack className="text-[#151720]/60" />
                    {backLabel}
                  </button>
                  <div className="border-t border-black/10" />
                  <div className="py-4 text-[#151720] font-bold uppercase tracking-[0.08em]">
                    {tMenu(activeItem.labelKey)}
                  </div>
                  <motion.ul
                    className="w-full divide-y divide-black/10"
                    initial="hidden"
                    animate="show"
                    variants={listVariants}
                  >
                    {activeItem.hasProgramsDropdown &&
                      visibleProgramsItems.map((menuItem) => {
                        const Icon = menuItem.icon;
                        return (
                          <motion.li key={menuItem.key} variants={itemVariants}>
                            <Link
                              href={`/${menuItem.prettyKey}` as never}
                              className="flex items-center gap-2 py-3 text-[#151720]/70 font-semibold hover:text-[#151720] hover:bg-[#f5f2e8] border-l-2 border-transparent hover:border-[#151720]/40"
                              onClick={handleClose}
                            >
                              <Icon size={20} className="text-[#151720]/60" />
                              <span>{tPrograms(menuItem.labelKey)}</span>
                            </Link>
                          </motion.li>
                        );
                      })}
                    {activeItem.hasCategoryDropdown && (
                      <>
                        {activeItem.hasAllCategoryOption && (
                          <motion.li variants={itemVariants}>
                            <Link
                              href={activeItem.to}
                              className="block py-3 text-[#151720]/70 font-semibold uppercase hover:text-[#151720] hover:bg-[#f5f2e8] border-l-2 border-transparent hover:border-[#151720]/40"
                              onClick={handleClose}
                            >
                              {activeItem.labelKey === 'videos'
                                ? tCategory('allVideos')
                                : tCategory('everyone')}
                            </Link>
                          </motion.li>
                        )}
                        {metaAttributes110.map((category) => (
                          <motion.li key={category.key} variants={itemVariants}>
                            <Link
                              href={`${activeItem.to}/${category.prettyKey}` as never}
                              className="flex items-center gap-2 py-3 text-[#151720]/70 font-semibold uppercase hover:text-[#151720] hover:bg-[#f5f2e8] border-l-2 border-transparent hover:border-[#151720]/40"
                              onClick={handleClose}
                            >
                              <Image
                                className="aspect-square"
                                src={`/assets/images/icons/light/${category.icon}`}
                                alt={tCategories(category.labelKey)}
                                width={20}
                                height={20}
                              />
                              <span>{tCategories(category.labelKey)}</span>
                            </Link>
                          </motion.li>
                        ))}
                      </>
                    )}
                  </motion.ul>
                </div>
              )}
            </div>
          </motion.div>
        </nav>
      </div>
    </motion.div>
  );
};

export default MobileMenu;
