'use client';
import { useEffect, useRef, useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useQuery } from '@tanstack/react-query';
import { useAuth } from '@/lib/auth-context';
import { api, selectedOrgId, setSelectedOrgId } from '@/lib/api';
import { ThemeToggle } from '@/lib/theme';
import { IconBell } from '@/components/ui';
import { FloatSelect } from '@/components/float';
import { formatDateTime, formatRole, capitalizeFirst as cap } from '@/lib/format';
import { useOrgBrand, BrandMark } from '@/lib/org-branding';
import type { AuthUser } from '@/src/server/types/auth';
import { LoginAlerts } from './login-alerts';

const links = [
  { href: '/dashboard', label: 'Dashboard' },
  { href: '/actions', label: 'Deviations' },
  { href: '/kanban', label: 'Workflow Board' },
  { href: '/samples', label: 'QC Samples' },
  { href: '/calendar', label: 'Calendar' },
  { href: '/reports', label: 'Reports' },
  { href: '/announcements', label: 'Notices' },
  { href: '/departments', label: 'Departments', staff: true },
  { href: '/categories', label: 'Categories', staff: true },
  { href: '/users', label: 'Users', staff: true },
  { href: '/audit-logs', label: 'Audit Logs', admin: true },
  { href: '/organisations', label: 'Organisations', sup: true },
  { href: '/settings', label: 'Settings', admin: true },
];

function OrgSwitcher() {
  const { user } = useAuth();
  const [orgs, setOrgs] = useState<any[]>([]);
  const [sel, setSel] = useState<string | null>(null);
  useEffect(() => {
    if (user?.role !== 'super_admin') return;
    setSel(selectedOrgId());
    api.get('/api/v1/super/organisations?limit=100').then((r) => setOrgs(r.data ?? [])).catch(() => {});
  }, [user]);
  if (user?.role === 'super_admin') {
    return (
      <div className="mb-3">
        <FloatSelect label="Organisation context" id="org-context" value={sel ?? ''} onChange={(e) => {
          setSelectedOrgId(e.target.value || null); setSel(e.target.value || null);
          window.location.reload();
        }}>
          <option value="">All organisations</option>
          {orgs.map((o: any) => <option key={o.id} value={o.id}>{cap(o.name)} ({cap(o.status)})</option>)}
        </FloatSelect>
      </div>
    );
  }
  if (user?.organisation) {
    return <p className="text-xs mb-3 border rounded-xl px-3 py-2" style={{ color: 'var(--muted)', borderColor: 'var(--line)' }}>{user.organisation.name}</p>;
  }
  return null;
}

function Nav({ onNavigate, unread }: { onNavigate?: () => void; unread: number }) {
  const { user } = useAuth();
  const path = usePathname();
  const visible = links.filter(l => {
    if ((l as any).sup) return user?.role === 'super_admin';
    if ((l as any).admin) return user?.role === 'admin' || user?.role === 'super_admin';
    if ((l as any).staff) return user?.role !== 'employee';
    return true;
  });
  return (
    <nav aria-label="Primary">
      <ul className="flex flex-col gap-1">
        {visible.map(l => {
          const active = path === l.href || (l.href !== '/dashboard' && path.startsWith(l.href + '/'));
          return (
            <li key={l.href}>
              <Link
                href={l.href}
                aria-current={active ? 'page' : undefined}
                onClick={onNavigate}
                className={`flex items-center gap-2 px-3 py-2.5 rounded-xl text-sm font-medium transition whitespace-nowrap ${active ? 'nav-active' : 'hover:bg-slate-500/10'}`}
                style={active ? undefined : { color: 'var(--ink)' }}
              >
                <span className="flex-1">{l.label}</span>
                {l.href === '/announcements' && unread > 0 && (
                  <span className="badge bg-red-600 text-white !px-1.5" aria-label={`${unread} unread notices`}>{unread}</span>
                )}
              </Link>
            </li>
          );
        })}
      </ul>
    </nav>
  );
}

function SidebarBody({ onNavigate, unread }: { onNavigate?: () => void; unread: number }) {
  const { logout } = useAuth();
  const { brand, logo } = useOrgBrand();
  return (
    <div className="flex flex-col h-full gap-4">
      <div>
        <BrandMark brand={brand} logo={logo} />
      </div>
      <OrgSwitcher />
      <div className="flex-1 overflow-y-auto -mx-1 px-1">
        <Nav onNavigate={onNavigate} unread={unread} />
      </div>
      <button onClick={() => { onNavigate?.(); logout(); }} className="btn-ghost btn-sm w-full">Logout</button>
    </div>
  );
}

const PAGE_TITLES: [RegExp, string][] = [
  [/^\/dashboard$/, 'Dashboard'],
  [/^\/actions\/[^/]+$/, 'Deviation details'],
  [/^\/actions/, 'Deviations'],
  [/^\/kanban/, 'Workflow Board'],
  [/^\/samples/, 'QC Samples'],
  [/^\/calendar/, 'Calendar'],
  [/^\/reports/, 'Reports'],
  [/^\/notifications/, 'Notifications'],
  [/^\/announcements/, 'Notices'],
  [/^\/departments/, 'Departments'],
  [/^\/categories/, 'Categories'],
  [/^\/users/, 'User Management'],
  [/^\/audit-logs/, 'Audit Logs'],
  [/^\/organisations/, 'Organisations'],
  [/^\/settings/, 'Settings'],
];

/** Dynamic browser-tab title for every dashboard page. */
function usePageTitle(path: string) {
  useEffect(() => {
    const hit = PAGE_TITLES.find(([re]) => re.test(path));
    document.title = `${hit ? hit[1] : 'Qtrial'} — Qtrial`;
  }, [path]);
}

export default function DashShell({ children, user }: { children: React.ReactNode; user: AuthUser }) {
  const { logout } = useAuth();
  const [drawer, setDrawer] = useState(false);
  const path = usePathname();
  usePageTitle(path);
  const unreadQ = useQuery({
    queryKey: ['ann-unread'], queryFn: () => api.get('/api/v1/announcements?limit=1'),
    enabled: true, staleTime: 60000,
  });
  const unread = unreadQ.data?.unread ?? 0;
  const notifQ = useQuery({
    queryKey: ['notif-unread'], queryFn: () => api.get('/api/v1/notifications?limit=1'),
    enabled: true, staleTime: 60000,
  });
  const notifUnread = notifQ.data?.unread ?? 0;
  const latestQ = useQuery({
    queryKey: ['notif-latest'], queryFn: () => api.get('/api/v1/notifications?limit=5'),
    enabled: true, staleTime: 30000,
  });
  const latest: any[] = latestQ.data?.data ?? [];
  const [bellOpen, setBellOpen] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const bellRef = useRef<HTMLDivElement>(null);
  const menuRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    if (!bellOpen && !menuOpen) return;
    const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') { setBellOpen(false); setMenuOpen(false); } };
    const onClick = (e: MouseEvent) => {
      if (bellRef.current && !bellRef.current.contains(e.target as Node)) setBellOpen(false);
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) setMenuOpen(false);
    };
    document.addEventListener('keydown', onKey);
    document.addEventListener('mousedown', onClick);
    return () => { document.removeEventListener('keydown', onKey); document.removeEventListener('mousedown', onClick); };
  }, [bellOpen, menuOpen]);
  const { brand: topBrand, logo: topLogo } = useOrgBrand();

  useEffect(() => { setDrawer(false); }, [path]);
  useEffect(() => {
    if (!drawer) return;
    const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setDrawer(false); };
    document.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
  }, [drawer]);

  const initial = user.name?.trim()?.charAt(0)?.toUpperCase() ?? '?';
  return (
    <div className="min-h-screen lg:grid lg:grid-cols-[240px_1fr]">
      <a href="#main" className="skip-link">Skip to content</a>

      {/* Desktop sidebar */}
      <aside className="hidden lg:block sticky top-0 h-screen border-r p-4 overflow-y-auto" style={{ background: 'var(--surface)', borderColor: 'var(--line)' }}>
        <SidebarBody unread={unread} />
      </aside>

      {/* Mobile drawer */}
      {drawer && (
        <div className="lg:hidden fixed inset-0 z-50" role="dialog" aria-modal="true" aria-label="Menu">
          <button aria-label="Close menu" onClick={() => setDrawer(false)} className="absolute inset-0 bg-black/50" tabIndex={-1} />
          <div className="absolute left-0 top-0 bottom-0 w-72 max-w-[85vw] p-4 shadow-xl overflow-y-auto" style={{ background: 'var(--surface)' }}>
            <div className="flex justify-end mb-2">
              <button onClick={() => setDrawer(false)} aria-label="Close menu" className="btn-ghost btn-icon">✕</button>
            </div>
            <SidebarBody onNavigate={() => setDrawer(false)} unread={unread} />
          </div>
        </div>
      )}

      <div className="min-w-0 flex flex-col min-h-screen">
        {/* Topbar */}
        <header className="sticky top-0 z-30 border-b" style={{ background: 'var(--surface)', borderColor: 'var(--line)' }}>
          <div className="flex items-center gap-2 px-4 py-2.5 max-w-6xl mx-auto w-full">
            <button
              className="btn-ghost btn-icon lg:hidden"
              onClick={() => setDrawer(true)}
              aria-expanded={drawer}
              aria-controls="mobile-menu"
              aria-label="Open menu"
            >
              ☰
            </button>
            <p className="font-bold lg:hidden"><BrandMark brand={topBrand} logo={topLogo} size={26} /></p>
            <div className="ml-auto flex items-center gap-2">
              <div className="relative" ref={bellRef}>
                <button
                  type="button"
                  onClick={() => { setBellOpen(v => !v); setMenuOpen(false); latestQ.refetch(); }}
                  aria-expanded={bellOpen}
                  aria-label={notifUnread > 0 ? `Notifications, ${notifUnread} unread` : 'Notifications'}
                  title="Notifications"
                  className="btn-plain relative"
                >
                  <IconBell />
                  {notifUnread > 0 && (
                    <span className="absolute -top-0.5 -right-0.5 inline-flex min-w-4 h-4 px-1 items-center justify-center rounded-full bg-red-600 text-white text-[10px] font-bold leading-none">
                      {notifUnread > 99 ? '99+' : notifUnread}
                    </span>
                  )}
                </button>
                {bellOpen && (
                  <div className="absolute right-0 mt-2 w-80 max-w-[85vw] rounded border shadow-lg overflow-hidden" style={{ background: 'var(--surface)', borderColor: 'var(--line)' }} role="menu" aria-label="Latest notifications">
                    <p className="px-3 py-2 text-xs font-semibold uppercase tracking-wider" style={{ color: 'var(--muted)' }}>
                      Latest notifications{notifUnread > 0 ? ` (${notifUnread} unread)` : ''}
                    </p>
                    {latest.length === 0 && <p className="px-3 py-3 text-sm" style={{ color: 'var(--muted)' }}>{latestQ.isLoading ? 'Loading…' : 'No notifications.'}</p>}
                    {latest.map((n: any) => (
                      <div key={n.id} className="px-3 py-2 border-t text-sm" style={{ borderColor: 'var(--line)' }}>
                        <p className="font-medium leading-tight">{n.title} {!n.is_read && <span className="badge bg-blue-600 text-white ml-1">new</span>}</p>
                        <p className="text-xs truncate" style={{ color: 'var(--muted)' }}>{n.message}</p>
                        <p className="text-[11px]" style={{ color: 'var(--muted)' }}>{formatDateTime(n.created_at)}</p>
                      </div>
                    ))}
                    <Link href="/notifications" onClick={() => setBellOpen(false)} className="block text-center text-sm font-semibold px-3 py-2.5 border-t hover:bg-slate-500/10" style={{ borderColor: 'var(--line)', color: 'var(--accent)' }}>
                      Show all notifications
                    </Link>
                  </div>
                )}
              </div>
              <ThemeToggle />
              <div className="relative" ref={menuRef}>
                <button
                  type="button"
                  onClick={() => { setMenuOpen(v => !v); setBellOpen(false); }}
                  aria-expanded={menuOpen}
                  aria-haspopup="menu"
                  aria-label={`Account menu for ${user.name}`}
                  title={`${user.name} (${formatRole(user.role)})`}
                  className="inline-flex h-10 w-10 items-center justify-center rounded-full text-sm font-bold"
                  style={{ background: 'var(--ink)', color: 'var(--bg)' }}
                >
                  <span aria-hidden="true">{initial}</span>
                </button>
                {menuOpen && (
                  <div className="absolute right-0 mt-2 w-56 rounded border shadow-lg overflow-hidden" style={{ background: 'var(--surface)', borderColor: 'var(--line)' }} role="menu" aria-label="Account">
                    <div className="px-3 py-2 border-b" style={{ borderColor: 'var(--line)' }}>
                      <p className="text-sm font-semibold truncate">{user.name}</p>
                      <p className="text-xs" style={{ color: 'var(--muted)' }}>{formatRole(user.role)}</p>
                    </div>
                    <Link href="/settings" onClick={() => setMenuOpen(false)} className="block px-3 py-2.5 text-sm hover:bg-slate-500/10" role="menuitem">
                      Profile settings
                    </Link>
                    <button onClick={() => { setMenuOpen(false); logout(); }} className="block w-full text-left px-3 py-2.5 text-sm hover:bg-slate-500/10" role="menuitem">
                      Logout
                    </button>
                  </div>
                )}
              </div>
            </div>
          </div>
        </header>
        <main id="main" tabIndex={-1} className="flex-1 w-full max-w-6xl mx-auto p-4 lg:p-6 outline-none">
          <LoginAlerts />
          {children}
        </main>
        <footer className="px-4 py-4 text-center text-xs" style={{ color: 'var(--muted)' }}>
          © 2026 Soulitum Labs. All rights reserved.
        </footer>
      </div>
    </div>
  );
}
