'use client';

import Link from 'next/link';
import { createPortal } from 'react-dom';
import { useCallback, useEffect, useState } from 'react';
import type { MenuNode } from '@/lib/api/types/menu';
import { NavTooltip } from '@/components/layout/nav-tooltip';
import {
  isLayoutOverviewNode,
  normalizeHref,
  isActivePath,
  visibleChildren,
  linkClass,
} from '@/components/layout/nav-shared';

function CascadeFolderPanel({
  title,
  nodes,
  pathname,
  onMenuNavigate,
  depth = 0,
}: {
  title: string;
  nodes: MenuNode[];
  pathname: string;
  onMenuNavigate?: (path: string, title: string) => void;
  depth?: number;
}) {
  const [openId, setOpenId] = useState<string | null>(null);

  const handleFolderKey = useCallback(
    (e: React.KeyboardEvent, nodeId: string) => {
      if (e.key === 'Enter' || e.key === 'ArrowRight') {
        e.preventDefault();
        setOpenId(nodeId);
      } else if (e.key === 'Escape') {
        setOpenId(null);
      }
    },
    [],
  );

  if (nodes.length === 0) {
    return null;
  }

  return (
    <div className="w-56 overflow-visible rounded-md border border-neutral-200 bg-white py-1 shadow-xl">
      <div className="border-b border-neutral-100 px-3 py-2 text-sm font-semibold text-neutral-900">{title}</div>
      <div className="relative overflow-visible py-1">
        {nodes.map((node) => {
          if (node.menu_type === 3) {
            return null;
          }
          const kids = visibleChildren(node);
          const hasKids = kids.length > 0;
          const pad = 8;

          const label = (
            <span className="flex min-w-0 items-center gap-2">
              {node.icon ? (
                <span className="shrink-0 text-neutral-500" aria-hidden>
                  {node.icon}
                </span>
              ) : null}
              <span className="truncate">{node.menu_name}</span>
            </span>
          );

          if (hasKids) {
            return (
              <div
                key={node.id}
                className="relative"
                onMouseEnter={() => setOpenId(node.id)}
              >
                <NavTooltip label={node.menu_name} delayDuration={0}>
                  <button
                    type="button"
                    className="flex w-full items-center justify-between rounded-md px-2 py-2 text-left text-sm text-neutral-800 hover:bg-neutral-100"
                    style={{ paddingLeft: pad }}
                    aria-expanded={openId === node.id}
                    onKeyDown={(e) => handleFolderKey(e, node.id)}
                  >
                    {label}
                    <span className="shrink-0 text-neutral-400" aria-hidden>
                      ›
                    </span>
                  </button>
                </NavTooltip>
                {openId === node.id ? (
                  <div
                    key={node.id}
                    className="cascade-flyout-sub absolute left-full top-0 ml-0 overflow-visible pl-0"
                    style={{ zIndex: 50 + depth }}
                  >
                    <CascadeFolderPanel
                      title={node.menu_name}
                      nodes={kids}
                      pathname={pathname}
                      onMenuNavigate={onMenuNavigate}
                      depth={depth + 1}
                    />
                  </div>
                ) : null}
              </div>
            );
          }

          const href = normalizeHref(node);
          const external = Boolean(node.external_link);
          const active = isLayoutOverviewNode(node)
            ? (pathname.replace(/\/$/, '') || '/') === '/dashboard'
            : isActivePath(pathname, href);

          if (href === '#') {
            return (
              <NavTooltip key={node.id} label={node.menu_name} delayDuration={0}>
                <div className="rounded-md px-2 py-2 text-sm text-neutral-500" style={{ paddingLeft: pad }}>
                  {label}
                </div>
              </NavTooltip>
            );
          }

          if (external) {
            return (
              <NavTooltip key={node.id} label={node.menu_name} delayDuration={0}>
                <a
                  href={href}
                  target="_blank"
                  rel="noopener noreferrer"
                  className={linkClass(false)}
                  style={{ paddingLeft: pad }}
                >
                  {label}
                </a>
              </NavTooltip>
            );
          }

          return (
            <NavTooltip key={node.id} label={node.menu_name} delayDuration={0}>
              <Link
                href={href}
                className={linkClass(active)}
                style={{ paddingLeft: pad }}
                onClick={() => onMenuNavigate?.(href, node.menu_name)}
                aria-current={active ? 'page' : undefined}
              >
                {label}
              </Link>
            </NavTooltip>
          );
        })}
      </div>
    </div>
  );
}

/** L2 起：fixed 根与一级行顶对齐；更深层级在面板内 absolute，与对应行顶对齐；无内部滚动 */
export function ClassicCascadeFlyoutPortal({
  rootNode,
  anchorRect,
  pathname,
  onMenuNavigate,
  onHoverEnter,
  onHoverLeave,
}: {
  rootNode: MenuNode;
  anchorRect: DOMRectReadOnly;
  pathname: string;
  onMenuNavigate?: (path: string, title: string) => void;
  onHoverEnter: () => void;
  onHoverLeave: () => void;
}) {
  const [mounted, setMounted] = useState(false);
  useEffect(() => setMounted(true), []);

  if (!mounted || typeof document === 'undefined') {
    return null;
  }

  const nodes = visibleChildren(rootNode);
  if (nodes.length === 0) {
    return null;
  }

  /** 左缘与一级导航右缘对齐，不向左叠在窄轨上（不再用负 overlap） */
  const left = anchorRect.right;

  return createPortal(
    <div
      className="pointer-events-auto fixed z-50 outline-none"
      style={{
        top: anchorRect.top,
        left,
        maxWidth: `calc(100vw - ${left}px - 8px)`,
      }}
      onMouseEnter={onHoverEnter}
      onMouseLeave={onHoverLeave}
    >
      <div key={rootNode.id} className="cascade-flyout-panel">
        <CascadeFolderPanel
          title={rootNode.menu_name}
          nodes={nodes}
          pathname={pathname}
          onMenuNavigate={onMenuNavigate}
        />
      </div>
    </div>,
    document.body,
  );
}
