"use client";
// 클라이언트 훅(useState/useEffect)을 사용하여 세션 표시/로그아웃을 처리합니다.
import Image from "next/image";
import Link from "next/link";
import { SearchBar } from "@/app/components/SearchBar";
import React from "react";
import { usePathname, useSearchParams } from "next/navigation";
import { SinglePageLogo } from "@/app/components/SinglePageLogo";

export function AppHeader() {
  const [categories, setCategories] = React.useState<Array<{ id: string; name: string; slug: string; boards: Array<{ id: string; name: string; slug: string }> }>>([]);
  const [openSlug, setOpenSlug] = React.useState<string | null>(null);
  const [megaOpen, setMegaOpen] = React.useState(false);
  const [mobileOpen, setMobileOpen] = React.useState(false);
  const headerRef = React.useRef<HTMLDivElement | null>(null);
  const [headerBottom, setHeaderBottom] = React.useState<number>(0);
  const navRefs = React.useRef<Record<string, HTMLAnchorElement | null>>({});
  const panelRef = React.useRef<HTMLDivElement | null>(null);
  const blockRefs = React.useRef<Record<string, HTMLDivElement | null>>({});
  const navItemRefs = React.useRef<Record<string, HTMLDivElement | null>>({});
  const [leftPositions, setLeftPositions] = React.useState<Record<string, number>>({});
  const [panelHeight, setPanelHeight] = React.useState<number>(0);
  const [blockWidths, setBlockWidths] = React.useState<Record<string, number>>({});
  const closeTimer = React.useRef<number | null>(null);
  const [navMinWidths, setNavMinWidths] = React.useState<Record<string, number>>({});

  // 현재 경로 기반 활성 보드/카테고리 계산
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const activeBoardId = React.useMemo(() => {
    if (!pathname) return null;
    const parts = pathname.split("/").filter(Boolean);
    if (parts[0] === "boards" && parts[1]) return parts[1];
    return null;
  }, [pathname]);
  const activeCategorySlug = React.useMemo(() => {
    if (activeBoardId) {
      const found = categories.find((c) => c.boards.some((b) => b.slug === activeBoardId));
      return found?.slug ?? null;
    }
    if (pathname === "/boards") {
      return searchParams?.get("category") ?? null;
    }
    return null;
  }, [activeBoardId, pathname, searchParams, categories]);

  const cancelClose = React.useCallback(() => {
    if (closeTimer.current) {
      window.clearTimeout(closeTimer.current);
      closeTimer.current = null;
    }
  }, []);

  const scheduleClose = React.useCallback(() => {
    cancelClose();
    closeTimer.current = window.setTimeout(() => {
      setMegaOpen(false);
      setOpenSlug(null);
    }, 150);
  }, [cancelClose]);
  // 카테고리 로드 + 외부에서 새로고침 트리거 지원
  const reloadCategories = React.useCallback(() => {
    fetch("/api/categories", { cache: "no-store" })
      .then((r) => r.json())
      .then((d) => setCategories(d?.categories || []))
      .catch(() => setCategories([]));
  }, []);
  React.useEffect(() => {
    reloadCategories();
    const onRefresh = () => reloadCategories();
    window.addEventListener("categories:reload", onRefresh);
    return () => window.removeEventListener("categories:reload", onRefresh);
  }, [reloadCategories]);

  // ESC로 메가메뉴 닫기
  React.useEffect(() => {
    if (!megaOpen) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") setMegaOpen(false);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [megaOpen]);

  // 헤더 bottom 좌표를 계산해 fixed 패널 top에 적용
  React.useEffect(() => {
    const measure = () => {
      const el = headerRef.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      setHeaderBottom(rect.bottom);
    };
    measure();
    window.addEventListener("resize", measure);
    window.addEventListener("scroll", measure, { passive: true });
    return () => {
      window.removeEventListener("resize", measure);
      window.removeEventListener("scroll", measure);
    };
  }, []);

  // (요구) 상위 카테고리 폭을 키우지 않음: 측정은 하되 상위 폭 업데이트는 하지 않음
  React.useEffect(() => {
    if (!categories.length) return;
    const measure = () => {
      // 상위 폭 미변경: 측정만 수행하고 상태는 건드리지 않음
    };
    // 레이아웃 안정화 이후(다음 두 프레임)에 1회 측정
    const raf1 = window.requestAnimationFrame(() => {
      const raf2 = window.requestAnimationFrame(() => measure());
      (measure as any)._raf2 = raf2;
    });
    const onResize = () => measure();
    window.addEventListener("resize", onResize);
    return () => {
      window.cancelAnimationFrame(raf1);
      if ((measure as any)._raf2) window.cancelAnimationFrame((measure as any)._raf2);
      window.removeEventListener("resize", onResize);
    };
  }, [categories]);

  // 초기 로드/리사이즈 시, 드롭다운 최종 폭을 선계산(상위 폭은 키우지 않음)
  React.useEffect(() => {
    if (!categories.length) return;
    const recomputeOnce = () => {
      const container = panelRef.current;
      if (!container) return;
      const containerRect = container.getBoundingClientRect();
      const nextPositions: Record<string, number> = {};
      const desiredWidths: Record<string, number> = {};
      const minWidthsBySlug: Record<string, number> = { community: 200 };
      categories.forEach((cat) => {
        const itemEl = navItemRefs.current[cat.slug];
        if (!itemEl) return;
        const r = itemEl.getBoundingClientRect();
        nextPositions[cat.slug] = Math.max(0, r.left - containerRect.left);
        const baseWidth = r.width; // 상위 아이템 실제 폭
        const minWidth = minWidthsBySlug[cat.slug] ?? baseWidth;
        const blockEl = blockRefs.current[cat.slug];
        let maxChildWidth = 0;
        if (blockEl) {
          const links = blockEl.querySelectorAll("a");
          links.forEach((a) => {
            const el = a as HTMLElement;
            const rectW = el.getBoundingClientRect().width;
            const cs = window.getComputedStyle(el);
            const ml = parseFloat(cs.marginLeft || "0");
            const mr = parseFloat(cs.marginRight || "0");
            const w = Math.ceil(rectW + ml + mr);
            if (w > maxChildWidth) maxChildWidth = w;
          });
          if (maxChildWidth === 0) {
            const contentEl = blockEl.firstElementChild as HTMLElement | null;
            maxChildWidth = Math.ceil(contentEl?.getBoundingClientRect().width ?? blockEl.getBoundingClientRect().width);
          }
        }
        // 하위 컨테이너 폭을 상위 폭으로 상한(clamp)
        const measuredSub = Math.max(maxChildWidth, 0);
        desiredWidths[cat.slug] = Math.min(baseWidth, Math.max(minWidth, measuredSub));
      });
      const finalWidths: Record<string, number> = {};
      const ordered = categories
        .filter((c) => typeof nextPositions[c.slug] === "number")
        .sort((a, b) => (nextPositions[a.slug]! - nextPositions[b.slug]!));
      ordered.forEach((cat, idx) => {
        const currentLeft = nextPositions[cat.slug]!;
        const desired = desiredWidths[cat.slug] ?? 0;
        const maxAvail = idx < ordered.length - 1
          ? Math.max(0, nextPositions[ordered[idx + 1].slug]! - currentLeft)
          : Math.max(0, containerRect.width - currentLeft);
        finalWidths[cat.slug] = Math.min(desired, maxAvail);
      });

      // 상태 업데이트는 변경된 경우에만 수행
      const eq = (a: Record<string, number>, b: Record<string, number>) => {
        const ka = Object.keys(a);
        const kb = Object.keys(b);
        if (ka.length !== kb.length) return false;
        for (const k of ka) { if (a[k] !== b[k]) return false; }
        return true;
      };
      setBlockWidths((prev) => (eq(prev, finalWidths) ? prev : finalWidths));
    };
    const raf = window.requestAnimationFrame(() => recomputeOnce());
    const onResize = () => recomputeOnce();
    window.addEventListener("resize", onResize);
    return () => {
      window.cancelAnimationFrame(raf);
      window.removeEventListener("resize", onResize);
    };
  }, [categories]);

  // 헤더 항목과 드롭다운 블록 정렬: 좌표 측정 및 패널 높이 계산
  React.useEffect(() => {
    if (!megaOpen) return;
    const compute = () => {
      const container = panelRef.current;
      if (!container) return;
      const containerRect = container.getBoundingClientRect();
      const nextPositions: Record<string, number> = {};
      const desiredWidths: Record<string, number> = {};
      const minWidthsBySlug: Record<string, number> = { community: 200 };
      categories.forEach((cat) => {
        const itemEl = navItemRefs.current[cat.slug];
        if (!itemEl) return;
        const r = itemEl.getBoundingClientRect();
        nextPositions[cat.slug] = Math.max(0, r.left - containerRect.left);
        const baseWidth = r.width; // 상위 항목 실제 폭
        const minWidth = minWidthsBySlug[cat.slug] ?? baseWidth;
        // 하위 카테고리(드롭다운) 버튼들의 최대 실제 폭(패딩+마진 포함) 측정
        const blockEl = blockRefs.current[cat.slug];
        let maxChildWidth = 0;
        if (blockEl) {
          const links = blockEl.querySelectorAll("a");
          links.forEach((a) => {
            const el = a as HTMLElement;
            const rectW = el.getBoundingClientRect().width;
            const cs = window.getComputedStyle(el);
            const ml = parseFloat(cs.marginLeft || "0");
            const mr = parseFloat(cs.marginRight || "0");
            const w = Math.ceil(rectW + ml + mr);
            if (w > maxChildWidth) maxChildWidth = w;
          });
          if (maxChildWidth === 0) {
            const contentEl = blockEl.firstElementChild as HTMLElement | null;
            maxChildWidth = Math.ceil(contentEl?.getBoundingClientRect().width ?? blockEl.getBoundingClientRect().width);
          }
        }
        // 하위 컨테이너 폭을 상위 폭으로 상한(clamp)
        const measuredSub = Math.max(maxChildWidth, 0);
        desiredWidths[cat.slug] = Math.min(baseWidth, Math.max(minWidth, measuredSub));
      });
      // 원하는 최소 폭을 기준으로 하되, 다음 항목의 시작점까지를 넘지 않도록 클램프
      const finalWidths: Record<string, number> = {};
      const ordered = categories
        .filter((c) => typeof nextPositions[c.slug] === "number")
        .sort((a, b) => (nextPositions[a.slug]! - nextPositions[b.slug]!));
      ordered.forEach((cat, idx) => {
        const currentLeft = nextPositions[cat.slug]!;
        const desired = desiredWidths[cat.slug] ?? 0;
        const maxAvail = idx < ordered.length - 1
          ? Math.max(0, nextPositions[ordered[idx + 1].slug]! - currentLeft)
          : Math.max(0, containerRect.width - currentLeft);
        finalWidths[cat.slug] = Math.min(desired, maxAvail);
      });
      setBlockWidths(finalWidths);

      // 우측 경계 초과 시 좌측으로 이동하여 뷰포트 안에 맞춤
      const finalLefts: Record<string, number> = {};
      ordered.forEach((cat) => {
        const currentLeft = nextPositions[cat.slug]!;
        const width = finalWidths[cat.slug] ?? 0;
        const maxLeft = Math.max(0, containerRect.width - width);
        finalLefts[cat.slug] = Math.max(0, Math.min(currentLeft, maxLeft));
      });
      setLeftPositions(finalLefts);

      // 상위 카테고리 최소 폭은 초기 측정(useEffect)에서만 설정

      // 패널 높이 = 블록들 중 최대 높이
      let maxH = 0;
      categories.forEach((cat) => {
        const el = blockRefs.current[cat.slug];
        if (el) maxH = Math.max(maxH, el.offsetHeight);
      });
      setPanelHeight(maxH);
    };
    compute();
    const onResize = () => compute();
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, [megaOpen, categories]);

  // xl 이상으로 뷰포트가 커지면 모바일 사이드바를 자동으로 닫음
  React.useEffect(() => {
    const mql = window.matchMedia("(min-width: 1280px)");
    const onChange = (e: any) => {
      if (e.matches) setMobileOpen(false);
    };
    // 초기 상태 체크 (이미 xl 이상인 경우 닫기)
    if (mql.matches) setMobileOpen(false);
    if (typeof mql.addEventListener === "function") {
      mql.addEventListener("change", onChange);
    } else {
      // Safari 등 구형 브라우저 호환
      mql.addListener(onChange);
    }
    return () => {
      if (typeof mql.removeEventListener === "function") {
        mql.removeEventListener("change", onChange);
      } else {
        mql.removeListener(onChange);
      }
    };
  }, []);
  return (
    <header ref={headerRef} className="relative flex items-center justify-between px-4 py-3  bg-white/80 backdrop-blur supports-[backdrop-filter]:bg-white/60">
      <div className="flex items-center gap-3 z-[100]">
        <button
          aria-label="메뉴 열기"
          aria-expanded={mobileOpen}
          aria-controls="mobile-menu"
          onClick={() => setMobileOpen((v) => !v)}
          className="inline-flex h-8 w-8 items-center justify-center rounded-md border border-neutral-200 xl:hidden"
        >
          <span className="flex flex-col items-center justify-center gap-1">
            <span className="block h-0.5 w-4 bg-neutral-800" />
            <span className="block h-0.5 w-4 bg-neutral-800" />
            <span className="block h-0.5 w-4 bg-neutral-800" />
          </span>
        </button>
        <Link href="/" aria-label="홈" className="shrink-0">
          <SinglePageLogo width={120} height={28} className="w-20 xl:w-[120px] h-auto" />
        </Link>
      </div>
      <nav className="flex flex-1 items-center gap-4 justify-between">
        {/* 데스크톱 메가메뉴 */}
        <div
          className="relative hidden xl:block pl-10"
          onMouseEnter={() => { cancelClose(); setMegaOpen(true); }}
          onMouseLeave={() => { scheduleClose(); }}
          onFocusCapture={() => setMegaOpen(true)}
          onBlurCapture={(e) => {
            const next = (e as unknown as React.FocusEvent<HTMLDivElement>).relatedTarget as Node | null;
            if (!e.currentTarget.contains(next)) setMegaOpen(false);
          }}
        >
          <div className="flex items-center gap-8">
            {categories.map((cat, idx) => (
              <div
                key={cat.id}
                className="relative group min-w-[80px] text-center"
                onMouseEnter={() => setOpenSlug(cat.slug)}
                ref={(el) => {
                  navItemRefs.current[cat.slug] = el;
                }}
                style={idx === categories.length - 1 ? { minWidth: 120 } : undefined}
              >
                <Link
                  href={cat.boards?.[0]?.slug ? `/boards/${cat.boards[0].slug}` : `/boards?category=${cat.slug}`}
                  className={`block w-full px-2 py-2 text-sm font-medium transition-colors duration-200 hover:text-neutral-900 whitespace-nowrap ${
                    activeCategorySlug === cat.slug ? "text-neutral-900" : "text-neutral-700"
                  }`}
                  ref={(el) => {
                    navRefs.current[cat.slug] = el;
                  }}
                >
                  {cat.name}
                </Link>
                <span
                  className={`pointer-events-none absolute left-1 right-1 -bottom-0.5 h-0.5 origin-left rounded bg-neutral-900 transition-all duration-200 ${
                    (megaOpen && openSlug === cat.slug) || activeCategorySlug === cat.slug
                      ? "scale-x-100 opacity-100"
                      : "scale-x-0 opacity-0 group-hover:opacity-100 group-hover:scale-x-100"
                  }`}
                />
              </div>
            ))}
          </div>
          <div
            className={`fixed left-0 right-0 z-50 border-t bg-white shadow-[0_8px_24px_rgba(0,0,0,0.08)] transition-all duration-200 ${
              megaOpen ? "opacity-100" : "pointer-events-none opacity-0"
            }`}
            style={{ top: headerBottom }}
            onMouseEnter={() => { cancelClose(); setMegaOpen(true); }}
            onMouseLeave={() => { scheduleClose(); }}
          >
            <div className="px-4 py-4 w-full  mx-auto overflow-x-hidden">
              <div ref={panelRef} className="relative">
                {categories.map((cat) => (
                  <div
                    key={cat.id}
                    ref={(el) => {
                      blockRefs.current[cat.slug] = el;
                    }}
                    className="absolute top-0"
                    style={{ left: (leftPositions[cat.slug] ?? 0), width: blockWidths[cat.slug] ?? undefined }}
                  >
                    {/* <div className="mb-2 font-semibold text-neutral-800">{cat.name}</div> */}
                    <div className="mx-auto flex flex-col items-center gap-3 w-full">
                      {cat.boards.map((b) => (
                        <Link
                          key={b.id}
                          href={`/boards/${b.slug}`}
                          className={`rounded px-2 py-1 text-sm transition-colors duration-150 hover:bg-neutral-100 hover:text-neutral-900 text-center whitespace-nowrap ${
                            activeBoardId === b.slug ? "bg-neutral-100 text-neutral-900 font-medium" : "text-neutral-700"
                          }`}
                          aria-current={activeBoardId === b.slug ? "page" : undefined}
                        >
                          {b.name}
                        </Link>
                      ))}
                    </div>
                  </div>
                ))}
                <div style={{ height: panelHeight }} />
              </div>
            </div>
          </div>
        </div>
        <div id="dummy" className="block"></div>
        <div className="hidden xl:flex xl:flex-1 justify-end">
          <SearchBar/>
        </div>
      </nav>
      {mobileOpen && (
        <div  className="fixed inset-0 h-[100vh] z-40 bg-black/60 backdrop-blur-sm" onClick={() => setMobileOpen(false)}>
          <div className="absolute left-0 xl:top-0 h-[100vh] w-11/12 max-w-md bg-white p-4 shadow-xl overflow-y-auto" onClick={(e) => e.stopPropagation()}>
            <div className="mb-3 h-10 flex items-center justify-between">
            </div>
            <div className="flex flex-col gap-4">
              <SearchBar />
              <div className="grid grid-cols-2 gap-4">
                {categories.map((cat) => (
                  <div key={cat.id}>
                    <div className="mb-2 font-semibold text-neutral-800">{cat.name}</div>
                    <div className="flex flex-col gap-1">
                      {cat.boards.map((b) => (
                        <Link key={b.id} href={`/boards/${b.slug}`} onClick={() => setMobileOpen(false)} className="rounded px-2 py-1 text-neutral-700 hover:bg-neutral-100 hover:text-neutral-900">
                          {b.name}
                        </Link>
                      ))}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      )}
    </header>
  );
}


