'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import type { MenuNode } from '@/lib/api/types/menu';
import { NavTooltip } from '@/components/layout/nav-tooltip';
import {
  NavIconOrLabel,
  NavStateGuard,
  NavTreeItem,
  normalizeHref,
  layoutNavRootsFromApi,
  subtreeContainsActivePath,
  visibleChildren,
} from '@/components/layout/nav-shared';
import { useMenuNavigation } from '@/lib/hooks/use-menu-navigation';

export function IconSidebarLayout({
  items,
  loading,
  error,
  authed,
  onCloseMobile,
}: {
  items: MenuNode[];
  loading: boolean;
  error: string | null;
  authed: boolean;
  onMenuNavigate?: (path: string, title: string) => void;
  onCloseMobile?: () => void;
}) {
  const pathname = usePathname() ?? '/';
  const roots = useMemo(() => layoutNavRootsFromApi(items), [items]);
  const onMenuNavigate = useMenuNavigation();

  const findFlyoutRootForPath = useCallback(
    (path: string): MenuNode | null => {
      for (const r of roots) {
        const kids = visibleChildren(r);
        if (kids.length === 0) continue;
        if (subtreeContainsActivePath(r, path)) return r;
      }
      return null;
    },
    [roots],
  );

  const [flyoutRoot, setFlyoutRoot] = useState<MenuNode | null>(null);

  useEffect(() => {
    const next = findFlyoutRootForPath(pathname);
    setFlyoutRoot((prev) => {
      if (next) return next;
      if (prev && subtreeContainsActivePath(prev, pathname)) return prev;
      return null;
    });
  }, [pathname, findFlyoutRootForPath]);

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') setFlyoutRoot(null);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  const toggleFlyout = (root: MenuNode) => {
    setFlyoutRoot((r) => (r?.id === root.id ? null : root));
  };

  const railShell = (inner: React.ReactNode) => (
    <div className="flex h-full min-h-0 w-[72px] shrink-0 flex-col border-r border-neutral-100 bg-white">
      {inner}
    </div>
  );

  if (!authed || loading || error) {
    return railShell(
      <NavStateGuard authed={authed} loading={loading} error={error} onMenuNavigate={onMenuNavigate} />,
    );
  }

  return (
    <div className="flex h-full min-h-0">
      <div className="flex w-[72px] shrink-0 flex-col border-r border-neutral-100 bg-white">
        <div className="min-h-0 flex-1 overflow-y-auto px-1 py-1">
          <nav className="flex flex-col items-stretch gap-0.5" aria-label="主导航">
            {roots.map((node) => {
              const kids = visibleChildren(node);
              if (kids.length > 0) {
                const open = flyoutRoot?.id === node.id;
                return (
                  <NavTooltip key={node.id} label={node.menu_name}>
                    <button
                      type="button"
                      aria-expanded={open}
                      className={[
                        'flex h-10 w-full items-center justify-center rounded-md text-sm',
                        open
                          ? 'bg-neutral-200 text-neutral-900'
                          : 'text-neutral-700 hover:bg-neutral-100',
                      ].join(' ')}
                      onClick={() => toggleFlyout(node)}
                    >
                      <span className="truncate px-1 text-center leading-tight">
                        <NavIconOrLabel node={node} />
                      </span>
                    </button>
                  </NavTooltip>
                );
              }

              const href = normalizeHref(node);
              const external = Boolean(node.external_link);
              if (href === '#') {
                return (
                  <NavTooltip key={node.id} label={node.menu_name}>
                    <div className="flex h-10 items-center justify-center rounded-md px-1 text-center text-[11px] text-neutral-400">
                      <NavIconOrLabel node={node} className="text-base" />
                    </div>
                  </NavTooltip>
                );
              }
              if (external) {
                return (
                  <NavTooltip key={node.id} label={node.menu_name}>
                    <a
                      href={href}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="flex h-10 items-center justify-center rounded-md text-neutral-700 hover:bg-neutral-100"
                    >
                      <NavIconOrLabel node={node} />
                    </a>
                  </NavTooltip>
                );
              }
              return (
                <NavTooltip key={node.id} label={node.menu_name}>
                  <Link
                    href={href}
                    className="flex h-10 items-center justify-center rounded-md text-neutral-700 hover:bg-neutral-100"
                    onClick={() => {
                      onMenuNavigate(href, node.menu_name);
                      onCloseMobile?.();
                      setFlyoutRoot(null);
                    }}
                  >
                    <NavIconOrLabel node={node} />
                  </Link>
                </NavTooltip>
              );
            })}
          </nav>
        </div>
      </div>

      {flyoutRoot && visibleChildren(flyoutRoot).length > 0 ? (
        <div className="flex w-56 shrink-0 flex-col border-r border-neutral-100 bg-white shadow-sm">
          <div className="sticky top-0 z-10 flex h-10 shrink-0 items-center border-b border-neutral-100 bg-white px-3">
            <div className="truncate text-sm font-semibold text-neutral-900">{flyoutRoot.menu_name}</div>
          </div>
          <div className="min-h-0 flex-1 space-y-0.5 overflow-y-auto px-2 py-2">
            {visibleChildren(flyoutRoot).map((c) => (
              <NavTreeItem
                key={c.id}
                node={c}
                depth={0}
                pathname={pathname}
                iconFlyout
                onMenuNavigate={onMenuNavigate}
              />
            ))}
          </div>
        </div>
      ) : null}
    </div>
  );
}
