'use client';

import { useEffect, useMemo, useState, type ReactNode } from 'react';
import Link from 'next/link';
import { usePathname, useRouter } from 'next/navigation';
import {
  LayoutDashboard,
  Calendar,
  Stethoscope,
  ReceiptText,
  FileText,
  Bell,
  BarChart3,
  Banknote,
  Package,
  Monitor,
  UserCircle2,
  FolderCheck,
  Search,
  LogOut,
  Menu,
  X,
  ChevronsLeft,
  ChevronsRight,
  ArrowRightLeft,
  Star,
  Pill,
} from 'lucide-react';
import { useAuth } from '@/lib/auth-context';
import { DynamicLogo, StatusPill } from '@sehat/ui';
import { VerificationProvider } from '@/lib/verification-context';
import { VerificationBanner } from './verification-banner';

// ---------------------------------------------------------------------------
// Navigation manifest — mirrors the v1 doctor menu, reorganised for v2.
// ---------------------------------------------------------------------------

interface NavItem {
  label: string;
  href: string;
  icon: typeof LayoutDashboard;
  /** Optional group label rendered above the item. */
  group?: string;
  /** Key into the live badge map (e.g. 'refills'). */
  badgeKey?: 'refills';
}

const NAV: NavItem[] = [
  { label: 'Dashboard', href: '/dashboard', icon: LayoutDashboard, group: 'Workspace' },
  { label: 'Appointments', href: '/appointments', icon: Calendar },
  { label: 'Schedule', href: '/schedule', icon: Stethoscope },
  { label: 'Prescriptions', href: '/prescriptions', icon: ReceiptText },
  { label: 'Refills', href: '/refills', icon: Pill, badgeKey: 'refills' },
  { label: 'Consultation notes', href: '/consultation-notes', icon: FileText },
  { label: 'Stats', href: '/stats', icon: BarChart3, group: 'Practice' },
  { label: 'Earnings', href: '/earnings', icon: Banknote },
  { label: 'Feedback', href: '/feedback', icon: Star },
  { label: 'Package', href: '/package', icon: Package },
  { label: 'Documents', href: '/documents', icon: FolderCheck, group: 'Account' },
  { label: 'Profile', href: '/profile', icon: UserCircle2 },
  { label: 'Devices', href: '/devices', icon: Monitor },
  { label: 'Switch to patient', href: '/switch-to-patient', icon: ArrowRightLeft },
  { label: 'Notifications', href: '/notifications', icon: Bell },
];

const COLLAPSE_KEY = 'sehat.doctor.sidebarCollapsed';

interface DoctorShellProps {
  children: ReactNode;
}

export function DoctorShell({ children }: DoctorShellProps) {
  return (
    <VerificationProvider>
      <DoctorShellInner>{children}</DoctorShellInner>
    </VerificationProvider>
  );
}

function DoctorShellInner({ children }: DoctorShellProps) {
  const { user, loading } = useAuth();
  const router = useRouter();
  const pathname = usePathname();
  const [collapsed, setCollapsed] = useState(false);
  const [mobileOpen, setMobileOpen] = useState(false);
  const [navBadges, setNavBadges] = useState<{ refills: number }>({ refills: 0 });

  // Poll the refill queue length so the sidebar badge stays roughly fresh.
  // Best-effort: silent on 404 (endpoint not yet shipped) or any error.
  useEffect(() => {
    let cancelled = false;
    async function load() {
      try {
        const res = await fetch('/api/doctors/me/refills?status=pending', {
          cache: 'no-store',
        });
        if (!res.ok) return;
        const data = (await res.json()) as unknown;
        if (!cancelled && Array.isArray(data)) {
          setNavBadges((b) => ({ ...b, refills: data.length }));
        }
      } catch {
        // Silent — endpoint may not be available yet.
      }
    }
    void load();
    const id = setInterval(() => void load(), 60_000);
    return () => {
      cancelled = true;
      clearInterval(id);
    };
  }, [pathname]);

  // Restore the collapsed preference once on mount (client only).
  useEffect(() => {
    if (typeof window === 'undefined') return;
    const saved = window.localStorage.getItem(COLLAPSE_KEY);
    if (saved === '1') setCollapsed(true);
  }, []);

  useEffect(() => {
    if (typeof window === 'undefined') return;
    window.localStorage.setItem(COLLAPSE_KEY, collapsed ? '1' : '0');
  }, [collapsed]);

  // Close mobile drawer on route change.
  useEffect(() => {
    setMobileOpen(false);
  }, [pathname]);

  useEffect(() => {
    if (!user?.mustChangePassword || !pathname) return;
    if (pathname.startsWith('/force-password-change') || pathname.startsWith('/login')) return;
    router.replace('/force-password-change');
  }, [pathname, router, user?.mustChangePassword]);

  // Bypass shell on auth-only screens (and during the initial auth check).
  if (pathname?.startsWith('/login') || pathname?.startsWith('/force-password-change')) {
    return <>{children}</>;
  }
  if (!user && !loading) {
    // Auth guard — redirect to login client-side. We render nothing in the
    // meantime to avoid a flash of the dense workspace.
    if (typeof window !== 'undefined') router.replace('/login');
    return null;
  }

  return (
    <div className="flex min-h-screen bg-denseSurface-bg">
      {/* Mobile drawer backdrop */}
      {mobileOpen ? (
        <div
          className="fixed inset-0 z-40 bg-navy-900/40 md:hidden"
          aria-hidden
          onClick={() => setMobileOpen(false)}
        />
      ) : null}

      <Sidebar
        collapsed={collapsed}
        mobileOpen={mobileOpen}
        onToggleCollapsed={() => setCollapsed((c) => !c)}
        onCloseMobile={() => setMobileOpen(false)}
        currentPath={pathname ?? ''}
        navBadges={navBadges}
      />

      <div className="flex min-w-0 flex-1 flex-col">
        <TopBar
          onOpenMobile={() => setMobileOpen(true)}
          currentPath={pathname ?? ''}
        />
        <VerificationBanner />
        <div className="min-w-0 flex-1">{children}</div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Sidebar
// ---------------------------------------------------------------------------

interface SidebarProps {
  collapsed: boolean;
  mobileOpen: boolean;
  onToggleCollapsed: () => void;
  onCloseMobile: () => void;
  currentPath: string;
  navBadges: { refills: number };
}

function Sidebar({
  collapsed,
  mobileOpen,
  onToggleCollapsed,
  onCloseMobile,
  currentPath,
  navBadges,
}: SidebarProps) {
  const widthCls = collapsed ? 'md:w-[60px]' : 'md:w-[240px]';

  return (
    <aside
      className={[
        'fixed inset-y-0 left-0 z-50 flex w-[260px] flex-col border-r border-navy-900 bg-navy-900 text-white transition-transform md:static md:translate-x-0',
        widthCls,
        mobileOpen ? 'translate-x-0' : '-translate-x-full md:translate-x-0',
      ].join(' ')}
    >
      <div className="flex h-14 items-center justify-between border-b border-white/5 px-3">
        <Link
          href="/dashboard"
          className="flex items-center gap-2 overflow-hidden"
        >
          <DynamicLogo
            variant="mark"
            size="sm"
            tone="mono-light"
            className="h-7 w-7"
          />
          {!collapsed ? (
            <div className="min-w-0 leading-tight">
              <p className="truncate text-[11px] uppercase tracking-wider text-white/60">
                Sehat Sahoolat
              </p>
              <p className="truncate text-sm font-semibold text-white">
                Doctor portal
              </p>
            </div>
          ) : null}
        </Link>
        <button
          type="button"
          className="md:hidden text-white/70 hover:text-white"
          onClick={onCloseMobile}
          aria-label="Close menu"
        >
          <X className="h-5 w-5" />
        </button>
      </div>

      <nav className="flex-1 overflow-y-auto px-2 py-3">
        {NAV.map((item, i) => {
          const prev = i > 0 ? NAV[i - 1] : null;
          const showGroup = item.group && item.group !== prev?.group;
          return (
            <div key={item.href}>
              {showGroup && !collapsed ? (
                <p className="mt-3 px-2 pb-1 text-[10px] font-semibold uppercase tracking-wider text-white/40">
                  {item.group}
                </p>
              ) : null}
              <NavLink
                item={item}
                collapsed={collapsed}
                currentPath={currentPath}
                badge={item.badgeKey ? navBadges[item.badgeKey] : 0}
              />
            </div>
          );
        })}
      </nav>

      <button
        type="button"
        onClick={onToggleCollapsed}
        className="hidden md:flex items-center justify-center gap-2 border-t border-white/5 px-3 py-2 text-xs text-white/60 hover:text-white"
        aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
      >
        {collapsed ? (
          <ChevronsRight className="h-4 w-4" />
        ) : (
          <>
            <ChevronsLeft className="h-4 w-4" />
            <span>Collapse</span>
          </>
        )}
      </button>
    </aside>
  );
}

function NavLink({
  item,
  collapsed,
  currentPath,
  badge,
}: {
  item: NavItem;
  collapsed: boolean;
  currentPath: string;
  badge: number;
}) {
  const isActive =
    currentPath === item.href ||
    (item.href !== '/dashboard' && currentPath.startsWith(item.href));
  const Icon = item.icon;
  return (
    <Link
      href={item.href}
      className={[
        'group relative flex items-center gap-3 rounded-md px-2 py-2 text-sm transition-colors',
        isActive
          ? 'bg-white/5 text-brand-300'
          : 'text-white/75 hover:bg-white/5 hover:text-white',
      ].join(' ')}
      title={collapsed ? item.label : undefined}
    >
      {isActive ? (
        <span
          aria-hidden
          className="absolute left-0 top-1/2 h-5 -translate-y-1/2 w-[3px] rounded-r bg-coral-500"
        />
      ) : null}
      <Icon className="h-4 w-4 flex-shrink-0" />
      {!collapsed ? <span className="truncate">{item.label}</span> : null}
      {badge > 0 ? (
        collapsed ? (
          <span
            aria-label={`${badge} pending`}
            className="absolute right-1 top-1 inline-flex h-2 w-2 rounded-full bg-coral-500"
          />
        ) : (
          <span className="ml-auto inline-flex h-5 min-w-[20px] items-center justify-center rounded-full bg-coral-500 px-1.5 text-[10px] font-bold text-white">
            {badge > 99 ? '99+' : badge}
          </span>
        )
      ) : null}
    </Link>
  );
}

// ---------------------------------------------------------------------------
// Top bar
// ---------------------------------------------------------------------------

function buildBreadcrumb(currentPath: string): string[] {
  if (!currentPath) return ['Dashboard'];
  const parts = currentPath.split('/').filter(Boolean);
  if (parts.length === 0) return ['Dashboard'];
  const labelled = parts.map((p) =>
    p
      .replace(/-/g, ' ')
      .replace(/^\w/, (c) => c.toUpperCase())
      .replace(/(\b\w{8,}-?)/g, (m) =>
        m.length > 12 ? `${m.slice(0, 6)}…` : m,
      ),
  );
  return labelled;
}

function TopBar({
  onOpenMobile,
  currentPath,
}: {
  onOpenMobile: () => void;
  currentPath: string;
}) {
  const { user, logout } = useAuth();
  const [searchOpen, setSearchOpen] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const [online, setOnline] = useState(true);
  const [unread, setUnread] = useState<number>(0);
  const crumbs = useMemo(() => buildBreadcrumb(currentPath), [currentPath]);

  // Best-effort unread badge — non-blocking.
  useEffect(() => {
    let cancelled = false;
    void (async () => {
      try {
        const res = await fetch('/api/notifications/unread-count', {
          cache: 'no-store',
        });
        if (!res.ok) return;
        const data = (await res.json()) as { unread?: number };
        if (!cancelled && typeof data.unread === 'number') setUnread(data.unread);
      } catch {
        // Silent — notifications may not be wired in this env.
      }
    })();
    return () => {
      cancelled = true;
    };
  }, []);

  // Cmd-K opens stub search modal. TODO(search): real global search.
  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        setSearchOpen(true);
      }
      if (e.key === 'Escape') setSearchOpen(false);
    }
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  async function toggleStatus() {
    const next = !online;
    setOnline(next);
    try {
      await fetch('/api/doctors/me/status', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ liveStatus: next ? 'online' : 'offline' }),
      });
    } catch {
      // Revert on failure.
      setOnline(!next);
    }
  }

  return (
    <header className="sticky top-0 z-30 flex h-14 items-center gap-3 border-b border-denseSurface-border bg-white px-4 shadow-sm">
      <button
        type="button"
        className="md:hidden text-ink-2 hover:text-ink-1"
        onClick={onOpenMobile}
        aria-label="Open menu"
      >
        <Menu className="h-5 w-5" />
      </button>

      <nav aria-label="Breadcrumb" className="hidden md:flex min-w-0 items-center gap-1.5 text-sm">
        {crumbs.map((c, i) => (
          <span key={i} className="flex items-center gap-1.5">
            {i > 0 ? <span className="text-ink-3">/</span> : null}
            <span
              className={
                i === crumbs.length - 1
                  ? 'font-semibold text-ink-1'
                  : 'text-ink-2'
              }
            >
              {c}
            </span>
          </span>
        ))}
      </nav>

      <div className="flex-1" />

      <button
        type="button"
        onClick={() => setSearchOpen(true)}
        className="hidden md:inline-flex items-center gap-2 rounded-md border border-denseSurface-border bg-denseSurface-bg px-2.5 py-1.5 text-xs text-ink-2 hover:bg-white"
      >
        <Search className="h-3.5 w-3.5" />
        <span>Search</span>
        <kbd className="rounded border border-denseSurface-border bg-white px-1.5 py-0.5 font-mono text-[10px] text-ink-3">
          ⌘K
        </kbd>
      </button>

      <button
        type="button"
        onClick={() => void toggleStatus()}
        className="inline-flex items-center"
        aria-label={online ? 'Go offline' : 'Go online'}
      >
        <StatusPill tone={online ? 'success' : 'coral'} dot>
          {online ? 'Online' : 'Offline'}
        </StatusPill>
      </button>

      <Link
        href="/notifications"
        className="relative inline-flex h-9 w-9 items-center justify-center rounded-md text-ink-2 hover:bg-denseSurface-bg hover:text-ink-1"
        aria-label="Notifications"
      >
        <Bell className="h-4 w-4" />
        {unread > 0 ? (
          <span className="absolute -right-0.5 -top-0.5 inline-flex h-4 min-w-[16px] items-center justify-center rounded-full bg-coral-500 px-1 text-[10px] font-bold text-white">
            {unread > 9 ? '9+' : unread}
          </span>
        ) : null}
      </Link>

      <div className="relative">
        <button
          type="button"
          onClick={() => setMenuOpen((m) => !m)}
          className="inline-flex items-center gap-2 rounded-md px-2 py-1 hover:bg-denseSurface-bg"
        >
          <div className="flex h-8 w-8 items-center justify-center rounded-full bg-gradient-hero-dense text-xs font-semibold text-white">
            {(user?.firstName ?? '?').slice(0, 1).toUpperCase()}
            {(user?.lastName ?? '').slice(0, 1).toUpperCase()}
          </div>
          <div className="hidden lg:block text-left text-xs leading-tight">
            <p className="font-semibold text-ink-1">
              Dr. {user?.firstName ?? ''} {user?.lastName ?? ''}
            </p>
            <p className="text-ink-3">{user?.email ?? ''}</p>
          </div>
        </button>
        {menuOpen ? (
          <div
            className="absolute right-0 top-full mt-1 w-52 rounded-md border border-denseSurface-border bg-white py-1 shadow-md"
            onMouseLeave={() => setMenuOpen(false)}
          >
            <Link
              href="/profile"
              className="flex items-center gap-2 px-3 py-2 text-sm text-ink-1 hover:bg-denseSurface-bg"
              onClick={() => setMenuOpen(false)}
            >
              <UserCircle2 className="h-4 w-4 text-ink-2" /> Your profile
            </Link>
            <Link
              href="/devices"
              className="flex items-center gap-2 px-3 py-2 text-sm text-ink-1 hover:bg-denseSurface-bg"
              onClick={() => setMenuOpen(false)}
            >
              <Monitor className="h-4 w-4 text-ink-2" /> Devices
            </Link>
            <div className="my-1 border-t border-denseSurface-border" />
            <button
              type="button"
              onClick={() => {
                setMenuOpen(false);
                void logout();
              }}
              className="flex w-full items-center gap-2 px-3 py-2 text-left text-sm text-danger-500 hover:bg-denseSurface-bg"
            >
              <LogOut className="h-4 w-4" /> Sign out
            </button>
          </div>
        ) : null}
      </div>

      {searchOpen ? (
        <div
          className="fixed inset-0 z-50 flex items-start justify-center bg-navy-900/30 p-4 pt-32"
          onClick={() => setSearchOpen(false)}
        >
          <div
            className="w-full max-w-xl rounded-lg border border-denseSurface-border bg-white p-5 shadow-lg"
            onClick={(e) => e.stopPropagation()}
          >
            <div className="flex items-center gap-2">
              <Search className="h-4 w-4 text-ink-3" />
              <input
                type="text"
                placeholder="Search patients, appointments, prescriptions…"
                autoFocus
                className="flex-1 bg-transparent text-sm text-ink-1 outline-none placeholder:text-ink-3"
              />
              <kbd className="rounded border border-denseSurface-border bg-denseSurface-bg px-1.5 py-0.5 font-mono text-[10px] text-ink-3">
                Esc
              </kbd>
            </div>
            <p className="mt-4 rounded-md border border-dashed border-denseSurface-border bg-denseSurface-bg p-3 text-xs text-ink-2">
              {/* TODO(search): hook up a real global search index. */}
              Global search is coming soon — for now use the menu on the left.
            </p>
          </div>
        </div>
      ) : null}
    </header>
  );
}
