"use client";

import { Fragment, useCallback, useRef, useState } from "react";
import { ChevronDown, ChevronRight } from "lucide-react";
import { MenuItemActions } from "./MenuItemActions";

type UIMenu = {
  id: string;
  name: string;
  icon?: React.ReactNode;
  hasChildren?: boolean;
  children?: UIMenu[];
  url?: string;
  badge?: number;
};

type TopNavBarProps = {
  menus: UIMenu[];
  isMenuActive: (m: UIMenu) => boolean;
  onSelect: (m: UIMenu) => void;
};

/**
 * TopNav — 디자인시스템 `TopNav` 포팅 (shell-components.jsx).
 * invyone 메뉴 트리(최상위 = 섹션)에 맞게 단순화.
 * 섹션 hover → flyout (첫 번째 레벨), flyout 아이템에 자식이 있으면 hover 로 2단계 sub-flyout.
 * leaf 항목 + url 이 대시보드 패턴(/{seq}) 이면 우클릭 컨텍스트 메뉴(이름 변경/삭제) 노출.
 */
export function TopNavBar({ menus, isMenuActive, onSelect }: TopNavBarProps) {
  const [openId, setOpenId] = useState<string | null>(null);
  const closeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const cancelClose = useCallback(() => {
    if (closeTimer.current) {
      clearTimeout(closeTimer.current);
      closeTimer.current = null;
    }
  }, []);
  const scheduleClose = useCallback(() => {
    cancelClose();
    // 섹션 헤더 → flyout 이동 중 마우스가 경계 근처에서 순간적으로 빠져도 안 닫히도록 여유있게.
    closeTimer.current = setTimeout(() => setOpenId(null), 260);
  }, [cancelClose]);
  const openNow = useCallback(
    (id: string) => {
      cancelClose();
      setOpenId(id);
    },
    [cancelClose],
  );

  const handleSectionClick = (m: UIMenu) => {
    // leaf 섹션은 바로 선택. 자식이 있는 섹션은 첫 leaf 로 점프.
    if (!m.hasChildren) {
      onSelect(m);
      return;
    }
    const first = m.children?.[0];
    if (!first) return;
    if (first.hasChildren && first.children?.[0]) onSelect(first.children[0]);
    else onSelect(first);
  };

  return (
    <nav className="v5-topnav" aria-label="주 내비게이션">
      {menus.map((sec, i) => {
        const isOpen = openId === sec.id;
        const isActive = isMenuActive(sec);
        return (
          <Fragment key={sec.id}>
            {i > 0 && <span className="v5-hdr-sep" aria-hidden="true" />}
            <MenuItemActions
              menuUrl={!sec.hasChildren ? sec.url : undefined}
              menuName={sec.name}
            >
              <div
                className={`v5-tn-section ${isActive ? "on" : ""} ${isOpen ? "open" : ""}`}
                onMouseEnter={() => openNow(sec.id)}
                onMouseLeave={scheduleClose}
                style={{ animationDelay: `${i * 40}ms` }}
              >
                <button
                  type="button"
                  className="v5-tn-item"
                  onClick={() => handleSectionClick(sec)}
                >
                  {sec.icon && <span className="v5-tn-ic">{sec.icon}</span>}
                  <span>{sec.name}</span>
                  {sec.hasChildren && <ChevronDown size={12} />}
                </button>

                {isOpen && sec.hasChildren && (
                  /*
                    flyout 의 onMouseEnter/Leave 는 의도적으로 달지 않음.
                    - flyout 은 section 의 DOM 자식이므로, section 의 mouseleave 는
                      "마우스가 flyout 과 section 모두 벗어났을 때" 에만 발화함.
                    - 따라서 섹션 내부 ↔ flyout 이동은 아무 이벤트도 발사되지 않고 유지됨.
                    - 이전엔 flyout mouseleave → scheduleClose 가 타서 섹션 쪽으로
                      위로 이동 시 플라이아웃이 사라지던 버그가 있었음.
                  */
                  <div className="v5-tn-flyout">
                    {sec.children?.map((it, j) => (
                      <TnRow
                        key={it.id}
                        item={it}
                        isMenuActive={isMenuActive}
                        onSelect={(x) => {
                          onSelect(x);
                          setOpenId(null);
                        }}
                        delay={j * 28}
                      />
                    ))}
                  </div>
                )}
              </div>
            </MenuItemActions>
          </Fragment>
        );
      })}
    </nav>
  );
}

function TnRow({
  item,
  isMenuActive,
  onSelect,
  delay,
}: {
  item: UIMenu;
  isMenuActive: (m: UIMenu) => boolean;
  onSelect: (m: UIMenu) => void;
  delay: number;
}) {
  const [subOpen, setSubOpen] = useState(false);
  const hasChildren = !!item.hasChildren && !!item.children?.length;
  const isOn = isMenuActive(item);

  return (
    <MenuItemActions menuUrl={!hasChildren ? item.url : undefined} menuName={item.name}>
      <div
        className={`v5-tn-row ${isOn ? "on" : ""} ${hasChildren ? "has-sub" : ""}`}
        style={{ animationDelay: `${delay}ms` }}
        onMouseEnter={() => hasChildren && setSubOpen(true)}
        onMouseLeave={() => setSubOpen(false)}
        onClick={(e) => {
          if ((e.target as HTMLElement).closest(".v5-tn-sub")) return;
          if (hasChildren && item.children?.[0]) onSelect(item.children[0]);
          else onSelect(item);
        }}
      >
        {item.icon && <span className="v5-tn-ic">{item.icon}</span>}
        <span className="v5-tn-row-label">{item.name}</span>
        {typeof item.badge === "number" && item.badge > 0 && (
          <span className="v5-tn-badge">{item.badge}</span>
        )}
        {hasChildren && <ChevronRight size={12} />}
        {hasChildren && subOpen && (
          <div className="v5-tn-sub">
            {item.children?.map((c, k) => (
              <MenuItemActions
                key={c.id}
                menuUrl={!c.hasChildren ? c.url : undefined}
                menuName={c.name}
              >
                <div
                  className={`v5-tn-row v5-tn-sub-row ${isMenuActive(c) ? "on" : ""}`}
                  style={{ animationDelay: `${k * 22}ms` }}
                  onClick={(e) => {
                    e.stopPropagation();
                    onSelect(c);
                  }}
                >
                  {c.icon && <span className="v5-tn-ic">{c.icon}</span>}
                  <span className="v5-tn-row-label">{c.name}</span>
                  {typeof c.badge === "number" && c.badge > 0 && (
                    <span className="v5-tn-badge">{c.badge}</span>
                  )}
                </div>
              </MenuItemActions>
            ))}
          </div>
        )}
      </div>
    </MenuItemActions>
  );
}
