import { PATHS } from '@/shared/constants/paths';
import { motion } from 'framer-motion';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { MenuCategory } from '@/entities/menu/ui/menu-category';
import { FavoriteWrapper } from '@/entities/home/ui/favorite-wrapper';
import { useStore } from '@/shared/model/store';
import { FilterMotionDuration, FilterMotionStyle, FilterMotionVariants, MenuItems } from '@/entities/common/model/constant';
import { useEffect, useRef, useState } from 'react';
import { useLocation } from 'react-router';
import { setHomeReloadKey } from '@/pages/home/home-page';
import { useShortcutSaveMutation } from '@/entities/user/api/use-shortcut-save-mutation';
import { ShortcutSaveParams, ShortcutSaveResponse } from '@/entities/user/model/types';
import { useTranslation } from 'react-i18next';

// 상수 정의
const SCROLL_ANIMATION_DURATION = 800;
const SCROLL_UP_OFFSET_PX = 150;
const BUTTON_SCROLL_OFFSET = 30;

// 타입 정의
interface ShortButton {
  menuId: number;
  menuName: string;
  index: number;
}

export interface MenuProps {
  menuOn: boolean;
  setMenuOn: (menuOn: boolean) => void;
  favoriteEdit?: boolean;
}

export const Menu = ({
  menuOn,
  setMenuOn,
  favoriteEdit
}: MenuProps) => {
  const { i18n } = useTranslation();
  const userMids = useStore.getState().UserStore.userMids;
  const userMid = useStore.getState().UserStore.mid;
  const userInfo = useStore.getState().UserStore.userInfo;
  const location = useLocation();
  const { navigate } = useNavigate();

  const { mutateAsync: shortcutSave } = useShortcutSaveMutation();

  const [shortBtns, setShortBtns] = useState<ShortButton[]>([]);
  const [editMode, setEditMode] = useState(false);
  const [changeMenuId, setChangeMenuId] = useState<string>();
  const [shortBtnIdx, setShortBtnIdx] = useState(0);

  const buttonRefs = useRef<Array<HTMLDivElement>>([]);
  const scrollRef = useRef<HTMLDivElement>(null);
  const shortBtnScrollRef = useRef<HTMLDivElement>(null);
  const isButtonScrolling = useRef<boolean>(false);
  const scrollTimer = useRef<NodeJS.Timeout | null>(null);
  const lastScrollTop = useRef<number>(0);
  // const [menuIds, setMenuIds] = useState<Array<number | undefined>>([]);

  const callShortcutSave = () => {
    if(userInfo.usrid){
      let userFavorite = useStore.getState().UserStore.userFavorite;
      let menuIds = userFavorite.map((value, index) => {
        return value.menuId;
      });
      
      let params: ShortcutSaveParams = {
        usrid: userInfo.usrid,
        isDefault: false,
        menuIds: menuIds
      };
      shortcutSave(params).then((rs: ShortcutSaveResponse) => {
        
      });
    }
  };

  const onClickToNavigate = (path: string) => {
    onClickToMenuClose();
    navigate(path);
  };
  const scrollCategoryButtonToLeft = (index: number) => {
    const buttonElement = shortBtnScrollRef.current?.children[index] as HTMLElement;
    if (buttonElement && shortBtnScrollRef.current) {
      const scrollLeft = buttonElement.offsetLeft - BUTTON_SCROLL_OFFSET;
      shortBtnScrollRef.current.scrollTo({
        top: 0,
        left: scrollLeft,
        behavior: 'smooth'
      });
    }
  };

  const onClickToMenuNavigate = (menuId: number, index: number) => {
    isButtonScrolling.current = true;
    setShortBtnIdx(index);
    scrollCategoryButtonToLeft(index);

    const categoryElement = buttonRefs.current[index];
    if (categoryElement && scrollRef.current) {
      const scrollContainer = scrollRef.current;
      const containerStyle = window.getComputedStyle(scrollContainer);
      const paddingTop = parseFloat(containerStyle.paddingTop) || 0;
      const scrollPosition = categoryElement.offsetTop - paddingTop;

      lastScrollTop.current = scrollPosition;

      scrollContainer.scrollTo({
        top: scrollPosition,
        left: 0,
        behavior: 'smooth'
      });
    }

    if (scrollTimer.current) {
      clearTimeout(scrollTimer.current);
    }

    scrollTimer.current = setTimeout(() => {
      if (scrollRef.current) {
        const actualScrollTop = scrollRef.current.scrollTop;
        lastScrollTop.current = actualScrollTop;
        setShortBtnIdx(index);
      }
      isButtonScrolling.current = false;
    }, SCROLL_ANIMATION_DURATION);
  };
  const onClickToMenuClose = () => {
    if(editMode){
      setEditMode(false);
      callShortcutSave();
      
      // 여기에 저장 로직?
    }
    else{
      setMenuOn(false);
      if(location.pathname === PATHS.home){
        setHomeReloadKey();
      }
    }
  };
  
  const getMenuCategory = () => {
    let rs = [];
    for(let i=0;i<MenuItems.length;i++){
      if(MenuItems[i]){
        rs.push(
          <MenuCategory
            key={ `menu-category-${i}` }
            menuId={ MenuItems[i]?.menuId }
            iconFilePath={ MenuItems[i]?.iconFilePath }
            menuName={ MenuItems[i]?.menuName }
            subMenu={ MenuItems[i]?.subMenu }
            setMenuOn={ setMenuOn }
            editMode={ editMode }
            changeMenuId={ changeMenuId }
            setChangeMenuId= { setChangeMenuId }
            buttonRefs={ buttonRefs }
            itemIndex={ i }
          />
        );
      }
      
    }
    return rs;
  };

  const shortBtnsSetting = () => {
    const shortList: ShortButton[] = MenuItems.map((item, index) => ({
      menuId: item.menuId,
      menuName: i18n.language === 'en' && item.menuNameEng ? item.menuNameEng : item.menuName,
      index
    }));
    setShortBtns(shortList);
  };

  const getCurrentCategoryIndex = (scrollTop: number): number => {
    if (buttonRefs.current.length === 0 || !scrollRef.current) return 0;

    const containerStyle = window.getComputedStyle(scrollRef.current);
    const paddingTop = parseFloat(containerStyle.paddingTop) || 0;
    const adjustedScrollTop = scrollTop + paddingTop;

    // 뷰포트의 상단 기준점 (약간의 오프셋 추가)
    const viewportTopWithOffset = adjustedScrollTop + 50;

    // 현재 뷰포트에 가장 많이 보이는 카테고리 찾기
    for (let i = 0; i < buttonRefs.current.length; i++) {
      const element = buttonRefs.current[i];
      if (!element) continue;

      const currentTop = element.offsetTop;

      // 마지막 카테고리인 경우
      if (i === buttonRefs.current.length - 1) {
        if (viewportTopWithOffset >= currentTop) {
          return i;
        }
      } else {
        // 다음 카테고리가 있는 경우
        const nextElement = buttonRefs.current[i + 1];
        if (nextElement) {
          const nextTop = nextElement.offsetTop;

          // 현재 카테고리 영역 내에 뷰포트 상단이 있으면 선택
          if (viewportTopWithOffset >= currentTop && viewportTopWithOffset < nextTop) {
            return i;
          }
        }
      }
    }

    return 0;
  };

  const menuListScroll = () => {
    if (isButtonScrolling.current) return;

    const scrollTop = scrollRef.current?.scrollTop || 0;
    const currentIndex = getCurrentCategoryIndex(scrollTop);

    if (currentIndex !== shortBtnIdx) {
      setShortBtnIdx(currentIndex);
      scrollCategoryButtonToLeft(currentIndex);
    }

    lastScrollTop.current = scrollTop;
  };

  useEffect(() => {
    shortBtnsSetting();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [i18n.language]);

  useEffect(() => {
    if(favoriteEdit){
      setEditMode(favoriteEdit)
    }
  },[favoriteEdit]);

  // 메뉴가 열릴 때 초기화
  useEffect(() => {
    if (menuOn) {
      // 스크롤 위치 초기화
      if (scrollRef.current) {
        scrollRef.current.scrollTop = 0;
      }
      if (shortBtnScrollRef.current) {
        shortBtnScrollRef.current.scrollLeft = 0;
      }
      // 선택된 버튼 인덱스 초기화
      setShortBtnIdx(0);
      // lastScrollTop 초기화
      lastScrollTop.current = 0;
    }
  }, [menuOn]);
  
  return (
    <>
      <motion.div 
        className="full-menu-modal" 
        initial="hidden"
        animate={ (menuOn)? 'visible': 'hidden' }
        variants={ FilterMotionVariants }
        transition={ FilterMotionDuration }
        style={ FilterMotionStyle }
      >
        <div className="full-menu-container">
          <div className="full-menu-header">
            <div className="full-menu-title">{ userMid }</div>
            <div className="full-menu-actions">
              { !editMode && 
                <button 
                  className="full-menu-settings"
                  onClick={ () => onClickToNavigate(PATHS.setting) }
                >
                  <img 
                    src={ IMAGE_ROOT + '/ico_set.svg' } 
                    alt="설정" 
                  />
                </button>
              }
              <button 
                className="full-menu-close"
                onClick={ () => onClickToMenuClose() }
              >
                <img 
                  src={ IMAGE_ROOT + '/ico_close.svg' } 
                  alt="닫기"
                />
              </button>
            </div>
          </div>
            
          <div className="full-menu-top-nav">
          {
            <FavoriteWrapper
              usingType='menu'
              editMode={ editMode }
              setEditMode={ setEditMode }
              changeMenuId={ changeMenuId }
              setMenuOn={ setMenuOn }
            ></FavoriteWrapper>
          }
          </div>
            
          <div className="full-menu-keywords-wrap">
            <div
              className="full-menu-keywords"
              ref={ shortBtnScrollRef }
            >
            {
              shortBtns.map((value, index) => (
                <span
                  key={ `short-btn-${value.menuName}` }
                  className={ `keyword-tag ${(shortBtnIdx === index)? 'active': ''}` }
                  onClick={ () => onClickToMenuNavigate(value.menuId, index) }
                >{ value.menuName }</span>
              ))
            }
            </div>
          </div>

          <div
            className="full-menu-list"
            ref={ scrollRef }
            onScroll={ menuListScroll }
          >
          { getMenuCategory() }
          </div>
        </div>
      </motion.div>
    </>
  );
};