'use client';

import * as Collapsible from '@radix-ui/react-collapsible';
import Link from 'next/link';
import type { MenuNode } from '@/lib/api/types/menu';
import { NavTooltip } from '@/components/layout/nav-tooltip';

/** 布局固定「概览」，与 IAM nav 拼成同一棵树（不入库） */
export const LAYOUT_OVERVIEW_MENU_ID = '__layout_overview__';

export function isLayoutOverviewNode(node: MenuNode): boolean {
  return node.id === LAYOUT_OVERVIEW_MENU_ID;
}

export const layoutOverviewMenuNode: MenuNode = {
  id: LAYOUT_OVERVIEW_MENU_ID,
  parent_id: '',
  menu_name: '概览',
  menu_type: 2,
  path: '/dashboard',
  icon: '📊',
};

/** 将布局「概览」与 IAM nav 合并为侧栏顶层列表，便于组好完整结构再一次性渲染 */
export function layoutNavRootsFromApi(items: MenuNode[]): MenuNode[] {
  return [layoutOverviewMenuNode, ...items.filter((n) => n.menu_type !== 3)];
}

export function normalizeHref(node: MenuNode): string {
  if (node.external_link) {
    return node.external_link;
  }
  const p = node.path?.trim();
  if (!p) {
    return '#';
  }
  if (p.startsWith('http://') || p.startsWith('https://')) {
    return p;
  }
  return p.startsWith('/') ? p : `/${p}`;
}

export function isActivePath(pathname: string, href: string): boolean {
  if (!href || href === '#' || href.startsWith('http://') || href.startsWith('https://')) {
    return false;
  }
  if (pathname === href) {
    return true;
  }
  if (href !== '/' && pathname.startsWith(`${href}/`)) {
    return true;
  }
  return false;
}

export function linkClass(active: boolean): string {
  return [
    'block rounded-md px-2 py-2 text-sm',
    active
      ? 'bg-neutral-200 font-medium text-neutral-900'
      : 'text-neutral-800 hover:bg-neutral-100',
  ].join(' ');
}

/** 经典树：目录可展开，叶子为链接（用于经典侧栏与图标模式右侧浮层） */
export function NavTreeItem({
  node,
  depth,
  pathname,
  onInternalNavigate,
  onMenuNavigate,
  /** 图标模式浮层：二级及以下项之间额外增加 2px（space-y-0.5） */
  iconFlyout = false,
}: {
  node: MenuNode;
  depth: number;
  pathname: string;
  onInternalNavigate?: () => void;
  onMenuNavigate?: (path: string, title: string) => void;
  iconFlyout?: boolean;
}) {
  if (node.menu_type === 3) {
    return null;
  }

  const children = (node.children ?? []).filter((c) => c.menu_type !== 3);
  const hasChildren = children.length > 0;
  const pad = 10 + depth * 10;

  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 (hasChildren) {
    return (
      <Collapsible.Root defaultOpen className="min-w-0 select-none">
        <Collapsible.Trigger asChild>
          <button
            type="button"
            className="group 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 }}
          >
            {label}
            <span
              className="shrink-0 text-neutral-400 transition-transform duration-200 ease-out group-aria-expanded:rotate-0 motion-reduce:transition-none -rotate-90"
              aria-hidden
            >
              ▾
            </span>
          </button>
        </Collapsible.Trigger>
        <Collapsible.Content
          className="grid overflow-hidden transition-[grid-template-rows] duration-200 ease-in-out motion-reduce:transition-none data-[state=open]:grid-rows-[1fr] data-[state=closed]:grid-rows-[0fr]"
        >
          <div className="min-h-0">
            <div
              className={`ml-3 border-l border-neutral-200 pl-1${iconFlyout ? ' space-y-0.5' : ''}`}
            >
              {children.map((c) => (
                <NavTreeItem
                  key={c.id}
                  node={c}
                  depth={depth + 1}
                  pathname={pathname}
                  iconFlyout={iconFlyout}
                  onInternalNavigate={onInternalNavigate}
                  onMenuNavigate={onMenuNavigate}
                />
              ))}
            </div>
          </div>
        </Collapsible.Content>
      </Collapsible.Root>
    );
  }

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

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

  if (external) {
    return (
      <a
        href={href}
        target="_blank"
        rel="noopener noreferrer"
        className={linkClass(false)}
        style={{ paddingLeft: pad }}
      >
        {label}
      </a>
    );
  }

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

export function visibleChildren(node: MenuNode): MenuNode[] {
  return (node.children ?? []).filter((c) => c.menu_type !== 3);
}

/** 当前路径是否落在该节点子树内（用于图标模式自动展开浮层） */
export function subtreeContainsActivePath(node: MenuNode, pathname: string): boolean {
  if (isLayoutOverviewNode(node)) {
    const p = pathname.replace(/\/$/, '') || '/';
    return p === '/dashboard';
  }
  const href = normalizeHref(node);
  if (!node.external_link && href !== '#' && isActivePath(pathname, href)) {
    return true;
  }
  for (const c of visibleChildren(node)) {
    if (subtreeContainsActivePath(c, pathname)) {
      return true;
    }
  }
  return false;
}

/** 窄轨图标/文字切换：有 icon 显示 icon，否则显示菜单名 */
export function NavIconOrLabel({ node, className }: { node: MenuNode; className?: string }) {
  if (node.icon) {
    return (
      <span className={className ?? 'block text-base'} aria-hidden>
        {node.icon}
      </span>
    );
  }
  return <span className="line-clamp-2 px-1 text-center text-[11px] font-medium">{node.menu_name}</span>;
}

/** 侧栏未认证/加载中/出错三态守卫 */
export function NavStateGuard({
  authed,
  loading,
  error,
  onMenuNavigate,
  children,
}: {
  authed: boolean;
  loading: boolean;
  error: string | null;
  onMenuNavigate: (path: string, title: string) => void;
  children?: React.ReactNode;
}) {
  if (!authed) {
    return <div className="px-2 py-4 text-center text-[11px] text-neutral-500">登录后加载菜单</div>;
  }
  if (loading) {
    return <div className="px-2 py-4 text-center text-[11px] text-neutral-500">菜单加载中…</div>;
  }
  if (error) {
    return (
      <div className="min-h-0 flex-1 overflow-y-auto px-1 py-1">
        <NavTooltip label="概览">
          <Link
            href="/dashboard"
            className="flex h-10 w-full items-center justify-center rounded-md text-neutral-700 hover:bg-neutral-100"
            onClick={() => onMenuNavigate('/dashboard', '概览')}
          >
            <span className="text-base" aria-hidden>
              📊
            </span>
            <span className="sr-only">概览</span>
          </Link>
        </NavTooltip>
        <NavTooltip label={error}>
          <p className="mt-2 cursor-default px-1 text-center text-[11px] text-red-600">菜单失败</p>
        </NavTooltip>
      </div>
    );
  }
  return children;
}
