import { useState, useEffect, useMemo, type ComponentType, type ElementType, Suspense } from 'react';
import { motion } from 'motion/react';
import { Building2, ChevronRight, ShieldCheck } from 'lucide-react';
import { useAuth } from '../auth/useAuth';
import { DemoModeProvider } from './Blur';
import FeedbackFab from './FeedbackFab';
import { cn } from '../lib/cn';
import { LoadingState } from './ui/surface';

export interface ModuleConfig {
  id: string;
  label: string;
  icon: ComponentType<{ size?: number; className?: string }>;
  component?: ElementType;
  children?: ModuleConfig[];
}

function flattenModules(modules: ModuleConfig[]): ModuleConfig[] {
  return modules.flatMap((module) => module.children ?? [module]);
}

/** hash 一级段（`#<id>` 或 `#<id>/<sub>` 都只取 id） */
function getHashHead(): string {
  return window.location.hash.slice(1).split('/')[0];
}

function getInitialModule(modules: ModuleConfig[]): string {
  const head = getHashHead();
  if (modules.some((m) => m.id === head)) return head;
  return modules[0]?.id ?? '';
}

function getHashModule(modules: ModuleConfig[]): string {
  const head = getHashHead();
  return modules.some((m) => m.id === head) ? head : '';
}

export function Shell({ modules }: { modules: ModuleConfig[] }) {
  const flatModules = useMemo(() => flattenModules(modules), [modules]);
  const [activeModule, setActiveModule] = useState(() => getInitialModule(flattenModules(modules)));
  const [openGroupId, setOpenGroupId] = useState<string | null>(null);

  useEffect(() => {
    const onHashChange = () => {
      const h = getHashModule(flatModules);
      if (h) setActiveModule(h);
    };
    window.addEventListener('hashchange', onHashChange);
    return () => window.removeEventListener('hashchange', onHashChange);
  }, [flatModules]);

  useEffect(() => {
    if (!openGroupId) return undefined;
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') setOpenGroupId(null);
    };
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [openGroupId]);

  useEffect(() => {
    // 同步 hash 一段到当前模块：使用 replaceState 避免产生多余的 history 记录，
    // 否则在小程序/webview 环境下首次进入需要点两次返回才能退出。
    // 注意只比对一级段，避免把子模块写入的 `#<id>/<sub>` 二级段抹掉。
    if (getHashHead() !== activeModule) {
      const { pathname, search } = window.location;
      window.history.replaceState(null, '', `${pathname}${search}#${activeModule}`);
    }
  }, [activeModule]);

  const switchModule = (id: string) => {
    setOpenGroupId(null);
    if (getHashHead() === id) {
      setActiveModule(id);
      return;
    }
    const { pathname, search } = window.location;
    window.history.replaceState(null, '', `${pathname}${search}#${id}`);
    setActiveModule(id);
  };

  const ActiveComponent = flatModules.find((module) => module.id === activeModule)?.component ?? flatModules[0]?.component;

  const { user } = useAuth();
  const activeLabel = flatModules.find((module) => module.id === activeModule)?.label ?? '业务看板';
  const watermarkText = useMemo(() => {
    const name = user?.userName || '未登录';
    const time = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-');
    return `${name}-${time}`;
  }, [user]);

  return (
    <DemoModeProvider enabled={false}>
    <div className="enterprise-grid-bg flex min-h-screen">
      {/* 全局水印 */}
      <div className="fixed inset-0 pointer-events-none z-[9999] overflow-hidden" style={{ opacity: 0.06 }}>
        <div className="absolute inset-0" style={{
          backgroundImage: `url("data:image/svg+xml,${encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' width='320' height='200'><text x='50%' y='50%' text-anchor='middle' dominant-baseline='middle' font-size='14' font-family='sans-serif' fill='%23000' transform='rotate(-25 160 100)'>${watermarkText}</text></svg>`)}")`,
          backgroundRepeat: 'repeat',
        }} />
      </div>
      {/* Web 侧边栏 (md 及以上) */}
      <nav className="fixed left-0 top-0 z-50 hidden h-full w-20 flex-col items-center border-r border-white/10 bg-slate-950 px-2 py-4 text-white shadow-[12px_0_40px_rgba(15,23,42,0.16)] md:flex">
        <div className="mb-5 flex h-12 w-12 items-center justify-center rounded-2xl bg-white text-blue-600 shadow-lg shadow-blue-950/20">
          <Building2 size={22} />
        </div>
        <div className="flex w-full flex-1 flex-col items-center gap-2">
          {modules.map((m) => {
            const Icon = m.icon;
            const isGroup = Boolean(m.children?.length);
            const isActive = m.id === activeModule || Boolean(m.children?.some((child) => child.id === activeModule));
            const isOpen = openGroupId === m.id;
            return (
              <div key={m.id} className="relative">
                <button
                  type="button"
                  onClick={() => isGroup ? setOpenGroupId((current) => current === m.id ? null : m.id) : switchModule(m.id)}
                  aria-expanded={isGroup ? isOpen : undefined}
                  aria-haspopup={isGroup ? 'menu' : undefined}
                  className={cn(
                    'group relative flex h-16 w-16 flex-col items-center justify-center rounded-2xl text-[10px] font-black transition-all',
                    isActive ? 'text-white' : 'text-slate-400 hover:bg-white/8 hover:text-white',
                  )}
                  title={m.label}
                >
                  {isActive ? (
                    <motion.span layoutId="desktop-shell-active" className="absolute inset-0 rounded-2xl bg-blue-600 shadow-lg shadow-blue-950/30" transition={{ type: 'spring', stiffness: 430, damping: 34 }} />
                  ) : null}
                  <Icon size={21} className="relative mb-1" />
                  <span className="relative leading-tight">{m.label}</span>
                  {isGroup ? <ChevronRight size={11} className={cn('absolute right-1 top-1/2 -translate-y-1/2 transition-transform', isOpen && 'rotate-180')} /> : null}
                </button>
                {isGroup && isOpen ? (
                  <div role="menu" aria-label={`${m.label}二级菜单`} className="absolute left-[calc(100%+12px)] top-1/2 w-36 -translate-y-1/2 rounded-2xl border border-slate-700 bg-slate-900 p-2 shadow-2xl shadow-slate-950/30">
                    {m.children!.map((child) => {
                      const ChildIcon = child.icon;
                      const childActive = child.id === activeModule;
                      return (
                        <button key={child.id} type="button" role="menuitem" onClick={() => switchModule(child.id)} className={cn('flex h-11 w-full items-center gap-2 rounded-xl px-3 text-xs font-black transition-colors', childActive ? 'bg-blue-600 text-white' : 'text-slate-300 hover:bg-white/8 hover:text-white')}>
                          <ChildIcon size={16} />{child.label}
                        </button>
                      );
                    })}
                  </div>
                ) : null}
              </div>
            );
          })}
        </div>
        <div className="flex w-full flex-col items-center gap-2 border-t border-white/10 pt-3">
          <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-400/10 text-emerald-300 ring-1 ring-emerald-300/20" title={user?.userName || '当前用户'}>
            <ShieldCheck size={18} />
          </div>
          <div className="max-w-16 truncate text-center text-[9px] font-bold text-slate-400">{user?.userName || '未登录'}</div>
        </div>
      </nav>

      {/* 内容区 */}
      <main className="min-w-0 flex-1 pb-16 md:ml-20 md:pb-0" style={{ overflowX: 'clip' }}>
        <div className="pointer-events-none fixed left-20 right-0 top-0 z-20 hidden h-12 items-center border-b border-white/60 bg-white/55 px-6 text-xs font-bold text-slate-400 backdrop-blur-xl md:flex">
          <span className="text-slate-600">羚牛氢能 BI</span>
          <span className="mx-2 text-slate-300">/</span>
          <span>{activeLabel}</span>
        </div>
        <Suspense fallback={<div className="p-3 md:p-6"><LoadingState label="正在加载业务模块" /></div>}>
          {ActiveComponent && <ActiveComponent />}
        </Suspense>
        <FeedbackFab module={activeModule} />
      </main>

      {/* 移动端底部导航 (md 以下) */}
      <nav className="fixed inset-x-0 bottom-0 z-50 border-t border-white/70 bg-white/92 px-3 pb-[max(0.5rem,env(safe-area-inset-bottom))] pt-2 shadow-[0_-18px_40px_rgba(15,23,42,0.08)] backdrop-blur-xl md:hidden">
        <div className="grid gap-1" style={{ gridTemplateColumns: `repeat(${modules.length}, minmax(0, 1fr))` }}>
        {modules.map((m) => {
          const Icon = m.icon;
          const isGroup = Boolean(m.children?.length);
          const isActive = m.id === activeModule || Boolean(m.children?.some((child) => child.id === activeModule));
          const isOpen = openGroupId === m.id;
          return (
            <div key={m.id} className="relative flex justify-center">
              <button
                type="button"
                onClick={() => isGroup ? setOpenGroupId((current) => current === m.id ? null : m.id) : switchModule(m.id)}
                aria-expanded={isGroup ? isOpen : undefined}
                aria-haspopup={isGroup ? 'menu' : undefined}
                className={cn('relative flex min-h-12 w-full flex-col items-center justify-center gap-0.5 rounded-2xl text-[10px] font-medium transition-colors', isActive ? 'text-blue-700' : 'text-slate-400')}
              >
                {isActive ? (
                  <motion.span layoutId="mobile-shell-active" className="absolute inset-0 rounded-2xl bg-blue-50 ring-1 ring-blue-100" transition={{ type: 'spring', stiffness: 430, damping: 34 }} />
                ) : null}
                <Icon size={20} className="relative" />
                <span className="relative">{m.label}</span>
              </button>
              {isGroup && isOpen ? (
                <div role="menu" aria-label={`${m.label}二级菜单`} className="absolute bottom-[calc(100%+14px)] left-1/2 w-36 -translate-x-1/2 rounded-2xl border border-slate-200 bg-white p-2 shadow-2xl shadow-slate-900/15">
                  {m.children!.map((child) => {
                    const ChildIcon = child.icon;
                    const childActive = child.id === activeModule;
                    return (
                      <button key={child.id} type="button" role="menuitem" onClick={() => switchModule(child.id)} className={cn('flex h-11 w-full items-center gap-2 rounded-xl px-3 text-xs font-medium transition-colors', childActive ? 'bg-blue-50 text-blue-700' : 'text-slate-600 hover:bg-slate-50')}>
                        <ChildIcon size={16} />{child.label}
                      </button>
                    );
                  })}
                </div>
              ) : null}
            </div>
          );
        })}
        </div>
      </nav>
    </div>
    </DemoModeProvider>
  );
}
