"use client";

import React, { useEffect, useRef, useState } from "react";
import Link from "next/link";
import { MenuItem, MegaMenuCategory, SubMenuItem } from "@/types/navigation";

interface NavDropdownProps {
  item: MenuItem;
}

/**
 * Category/item-list mega-menu card. Not a port of the live Joomla template's
 * flat `#e3e3e3`/`#eaeaea` flyout (that version exists in prior history) —
 * this is the polished white-card design the user asked to bring back:
 * rounded card, category list on the left with a real item count per
 * category (`cat.items.length`, not a fabricated badge), and the selected
 * category's items on the right in a two-column grid.
 *
 * `alignRight` flips it to hang off the trigger's right edge instead of its
 * left — needed for nav items positioned near the right of the bar (e.g.
 * "Free Resources"), where an 840px-wide panel anchored `left-0` would
 * otherwise run off the viewport (verified: its right column was rendering
 * past the browser edge, cutting off labels like "Plagiarism Checker").
 */
function MegaMenuPanel({
  categories,
  offsetLeft,
  isOpen,
  onNavigate,
}: {
  categories: MegaMenuCategory[];
  offsetLeft: number | null;
  isOpen: boolean;
  onNavigate: () => void;
}) {
  const [activeCategory, setActiveCategory] = useState<string | null>(categories[0]?.categoryTitle ?? null);
  const active = categories.find((cat) => cat.categoryTitle === activeCategory) ?? categories[0];

  // Which subject-group item (e.g. "Management") in the middle column is
  // hovered, so its own real children ("Change Management Assignment", ...)
  // can flyout in a third column — the live site's actual structure
  // (`.sub-submenu` per subject), not a flattened single list. Resets
  // whenever the active category changes so a stale flyout from the
  // previous category can't linger.
  //
  // Defaults to the category's *first* item rather than `null` — the right
  // column's wrapper always renders now (see its own comment, below) so the
  // panel's width stays constant across every hover state; defaulting to
  // nothing hovered meant that fixed-width column sat empty until the user
  // actually hovered something, which read as a stray blank panel on open
  // rather than a populated mega-menu. Defaulting to the first item means
  // there's real content there from the first paint in the common case
  // (most subject items have real children — see AGENTS.md's "Management"
  // example), and it still correctly shows nothing for the rare item that
  // genuinely has none.
  const [hoveredItem, setHoveredItem] = useState<SubMenuItem | null>(categories[0]?.items[0] ?? null);
  const flyoutItem = hoveredItem && active?.items.includes(hoveredItem) ? hoveredItem : null;

  // Once the mouse leaves the whole bar and the panel closes, drop back to
  // the first category with its first item pre-selected — so reopening it
  // always starts fresh (populated, not blank) instead of reappearing
  // wherever the last visit left off.
  useEffect(() => {
    if (isOpen) return;
    setActiveCategory(categories[0]?.categoryTitle ?? null);
    setHoveredItem(categories[0]?.items[0] ?? null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen]);

  return (
    <div
      // Fixed static height (500px) and width (760px) so the panel size remains
      // completely stable without shrinking or growing when switching categories.
      className={`${isOpen ? "flex" : "hidden"} absolute top-full left-0 z-50 h-[500px] rounded-2xl border border-slate-100 bg-white shadow-xl overflow-hidden`}
      style={offsetLeft !== null ? { left: offsetLeft } : undefined}
    >
      {/* Left — category list: static height, no visible scrollbar */}
      <div className="w-[240px] shrink-0 border-r border-slate-100 p-3 h-full overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
        <ul>
          {categories.map((cat) => {
            const isActive = cat.categoryTitle === active?.categoryTitle;
            return (
              <li
                key={cat.categoryTitle}
                onMouseEnter={() => {
                  setActiveCategory(cat.categoryTitle);
                  // First item of the newly-active category keeps the right
                  // column populated instead of going blank on every switch.
                  setHoveredItem(cat.items[0] ?? null);
                }}
              >
                <Link
                  href={cat.categoryHref ?? "#"}
                  onClick={onNavigate}
                  prefetch={false}
                  className={`block rounded-lg px-3 py-2 text-sm font-medium transition-colors ${
                    isActive ? "bg-[#4E6C2F] text-white" : "text-[#2a2a2a] hover:bg-slate-50"
                  }`}
                >
                  {cat.categoryTitle}
                </Link>
              </li>
            );
          })}
        </ul>
      </div>

      {/* Middle — selected category's subject-group items: static height, no visible scrollbar */}
      <div className="w-[260px] shrink-0 border-r border-slate-100 p-3 h-full overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
        {active && active.items.length > 0 && (
          <ul>
            {active.items.map((sub) => (
              <li key={sub.href} onMouseEnter={() => setHoveredItem(sub)}>
                <Link
                  href={sub.href}
                  onClick={onNavigate}
                  prefetch={false}
                  className={`block rounded-lg px-3 py-1.5 text-sm transition-colors ${
                    flyoutItem?.href === sub.href
                      ? "bg-slate-100 text-[#4E6C2F]"
                      : "text-slate-600 hover:bg-slate-100 hover:text-[#4E6C2F]"
                  }`}
                >
                  {sub.label}
                </Link>
              </li>
            ))}
          </ul>
        )}
      </div>

      {/* Right — the hovered subject-group's own real task-page children.
          ONLY this last section has the visible styled scrollbar. */}
      <div className="w-[260px] shrink-0 p-3 h-full overflow-y-auto [scrollbar-width:thin] [scrollbar-color:#5c7a36_#f1f5f9] [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-slate-50 [&::-webkit-scrollbar-thumb]:bg-[#5c7a36]/60 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb:hover]:bg-[#5c7a36]">
        {flyoutItem?.children && flyoutItem.children.length > 0 && (
          <ul>
            {flyoutItem.children.map((sub) => (
              <li key={sub.href}>
                <Link
                  href={sub.href}
                  onClick={onNavigate}
                  prefetch={false}
                  className="block rounded-lg px-3 py-1.5 text-sm text-slate-600 transition-colors hover:bg-slate-50 hover:text-[#4E6C2F]"
                >
                  {sub.label}
                </Link>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}

// Real panel widths (see `MegaMenuPanel`'s `w-[240px]`+`w-[260px]`+`w-[260px]`
// columns, and the plain dropdown's `w-[280px]`), used to predict overflow
// from the trigger's own position rather than measuring the (hidden,
// zero-width) panel itself.
const MEGA_MENU_WIDTH = 240 + 260 + 260;
const SIMPLE_DROPDOWN_WIDTH = 280;

export const NavDropdown: React.FC<NavDropdownProps> = ({ item }) => {
  const isGroupedDropdown = !item.isMegaMenu && !!item.categories?.length;
  const isMega = (item.isMegaMenu || isGroupedDropdown) && !!item.categories;
  const wrapperRef = useRef<HTMLDivElement>(null);
  // Panel visibility is tracked explicitly (not pure CSS `:hover`) so a
  // click on a link can force it closed immediately. With pure `:hover`,
  // clicking a link navigates but the mouse hasn't moved — the header
  // persists across the client-side navigation, so the same DOM position
  // is still "hovered" and the panel stayed open, floating over the new
  // page until the user moved the mouse away.
  const [isOpen, setIsOpen] = useState(false);
  // `left` offset (px, relative to the trigger's own wrapper) that keeps the
  // panel fully on-screen with a 16px margin on both edges. A plain
  // left-0/right-0 flip pins the panel's edge exactly to the trigger's edge,
  // which for a wide (840px) panel triggered by a nav item sitting far to
  // the right (e.g. "Free Resources") pushes the panel's *other* edge well
  // past the viewport's left edge — spanning almost the entire header and
  // looking detached from its trigger. Clamping keeps it as close to the
  // trigger as the viewport allows instead of jumping to a fixed edge.
  const [offsetLeft, setOffsetLeft] = useState<number | null>(null);

  useEffect(() => {
    if (!item.hasSubmenu) return;
    const panelWidth = isMega ? MEGA_MENU_WIDTH : SIMPLE_DROPDOWN_WIDTH;
    const margin = 16;
    const reposition = () => {
      // Skip running on mobile view where NavDropdown is hidden
      if (typeof window !== "undefined" && window.innerWidth < 1024) return;
      const rect = wrapperRef.current?.getBoundingClientRect();
      if (!rect) return;
      const maxViewportLeft = window.innerWidth - margin - panelWidth;
      const minViewportLeft = margin;
      const clampedViewportLeft = Math.max(minViewportLeft, Math.min(rect.left, maxViewportLeft));
      setOffsetLeft(clampedViewportLeft - rect.left);
    };
    if (typeof window !== "undefined" && window.innerWidth >= 1024) {
      reposition();
    }
    window.addEventListener("resize", reposition, { passive: true });
    return () => window.removeEventListener("resize", reposition);
  }, [item.hasSubmenu, isMega]);

  if (!item.hasSubmenu) {
    return (
      <Link
        href={item.href}
        className="relative text-sm text-[#2a2a2a] py-2 px-3 whitespace-nowrap after:absolute after:bottom-1.5 after:left-1/2 after:h-[2px] after:w-0 after:-translate-x-1/2 after:bg-[#4E6C2F] after:transition-[width] after:duration-300 hover:after:w-4/5 "
        style={{ fontFamily: "robotoregular" }}
      >
        {item.label}
      </Link>
    );
  }

  return (
    <div
      className="relative group/nav"
      ref={wrapperRef}
      onMouseEnter={() => setIsOpen(true)}
      onMouseLeave={() => setIsOpen(false)}
    >
      <button
        className="relative text-sm text-[#2a2a2a] py-2 px-3 whitespace-nowrap cursor-pointer after:absolute after:bottom-1.5 after:left-1/2 after:h-[2px] after:w-0 after:-translate-x-1/2 after:bg-[#4E6C2F] after:transition-[width] after:duration-300 group-hover/nav:after:w-4/5"
        style={{ fontFamily: "robotoregular" }}
        aria-haspopup="true"
        aria-expanded={isOpen}
      >
        {item.label}
      </button>

      {isMega && item.categories ? (
        <MegaMenuPanel
          categories={item.categories}
          offsetLeft={offsetLeft}
          isOpen={isOpen}
          onNavigate={() => setIsOpen(false)}
        />
      ) : (
        <div
          className={`${isOpen ? "block" : "hidden"} absolute top-full left-0 z-50 w-[280px] rounded-2xl border border-slate-100 bg-white p-2 shadow-xl`}
          style={offsetLeft !== null ? { left: offsetLeft } : undefined}
        >
          <ul>
            {item.subItems?.map((sub) => (
              <li key={sub.href}>
                <Link
                  href={sub.href}
                  onClick={() => setIsOpen(false)}
                  prefetch={false}
                  className="block rounded-lg px-3 py-2.5 text-sm text-[#2a2a2a] transition-colors hover:bg-slate-100 hover:text-[#4E6C2F]"
                >
                  {sub.label}
                </Link>
              </li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
};
