"use client";

import { useEffect, useState, useTransition } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { MenuIcon, LogOutIcon, Loader2Icon } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { logoutAction } from "@/actions/auth";
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "@/components/ui/sheet";
import {
  NAV_ITEMS,
  navItemsForRole,
  pickActiveNavKey,
  type NavItem,
  type NavRole,
} from "@/components/nav-config";

// ---------------------------------------------------------------------------
// Mobile header (sm:hidden)
//
// Single-row layout:
//   ┌──┐                        ┌────┐
//   │cm│   Page title           │menu│
//   └──┘                        └────┘
//
// The brand mark on the left links home. The page title (derived from
// the current nav route) gives the user a "you are here" cue without
// waiting for the page content to render. The menu button on the right
// opens a Sheet with the full nav list and the theme toggle.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Sign-out button used by both the desktop sidebar footer and the mobile
// drawer footer. Server-action under the hood: clears the session
// cookie and redirects to /login. Disabled while in flight so a
// double-click doesn't fire two redirects.
// ---------------------------------------------------------------------------
function SignOutButton({ username }: { username: string | null }) {
  const [pending, start] = useTransition();
  return (
    <div className="flex items-center justify-between gap-2">
      <div className="min-w-0">
        {username && (
          <p className="text-xs text-muted-foreground truncate">
            Signed in as <em className="italic font-medium text-foreground">{username}</em>
          </p>
        )}
      </div>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        disabled={pending}
        onClick={() => start(() => logoutAction())}
        aria-label="Sign out"
      >
        {pending ? (
          <Loader2Icon className="size-4 animate-spin" />
        ) : (
          <LogOutIcon className="size-4" />
        )}
        Sign out
      </Button>
    </div>
  );
}

function MobileHeader({
  items,
  username,
}: {
  items: NavItem[];
  username: string | null;
}) {
  const pathname = usePathname();
  const activeKey = pickActiveNavKey(items, pathname);
  const [open, setOpen] = useState(false);

  // Close the drawer when the route changes (i.e. the user picked a nav
  // item). Without this, navigating leaves the sheet open over the new
  // page until the user dismisses it manually.
  useEffect(() => {
    setOpen(false);
  }, [pathname]);

  // Use the full list (not the role-filtered one) for the title lookup
  // so the page title still shows up correctly when a 'user' role hits
  // a route they wouldn't normally see in the nav (e.g. arrives via a
  // direct link), even though they can't navigate there from the menu.
  const currentItem = NAV_ITEMS.find(({ href }) =>
    href === "/" ? pathname === "/" : pathname.startsWith(href),
  );
  const title = currentItem?.label ?? "WhatsApp Bot";

  return (
    <header className="fixed top-0 left-0 right-0 z-40 flex h-14 items-center justify-between border-b border-border bg-background/95 backdrop-blur-sm px-3 sm:hidden">
      <Link
        href="/"
        aria-label="Go home"
        className="flex size-9 items-center justify-center rounded-lg bg-primary text-xs font-bold uppercase text-primary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
      >
        cm
      </Link>

      <span className="truncate text-sm font-semibold tracking-tight px-2">
        {title}
      </span>

      <Sheet open={open} onOpenChange={setOpen}>
        <SheetTrigger asChild>
          <Button
            type="button"
            variant="ghost"
            size="icon-sm"
            aria-label="Open menu"
            className="size-9"
          >
            <MenuIcon className="size-5" />
          </Button>
        </SheetTrigger>
        <SheetContent side="right" className="flex w-72 flex-col gap-0 p-0">
          <SheetHeader className="gap-1 border-b border-border px-4 py-3">
            <SheetTitle className="flex items-center gap-2">
              <span
                aria-hidden
                className="flex size-6 items-center justify-center rounded-md bg-primary text-[10px] font-bold uppercase text-primary-foreground"
              >
                cm
              </span>
              WhatsApp Bot
            </SheetTitle>
            <SheetDescription className="sr-only">
              Primary navigation menu
            </SheetDescription>
          </SheetHeader>

          <nav
            aria-label="Primary navigation"
            className="flex flex-col gap-0.5 p-2"
          >
            {items.map(({ key, href, label, icon: Icon }) => {
              const active = activeKey === key;
              return (
                <Link
                  key={key}
                  // eslint-disable-next-line @typescript-eslint/no-explicit-any
                  href={href as any}
                  aria-current={active ? "page" : undefined}
                  className={cn(
                    "flex min-h-[44px] items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
                    active
                      ? "bg-accent text-accent-foreground"
                      : "text-foreground hover:bg-muted",
                  )}
                >
                  <Icon
                    size={18}
                    strokeWidth={active ? 2.5 : 1.75}
                    aria-hidden
                  />
                  {label}
                </Link>
              );
            })}
          </nav>

          <div className="mt-auto border-t border-border p-3">
            <SignOutButton username={username} />
          </div>
        </SheetContent>
      </Sheet>
    </header>
  );
}

// ---------------------------------------------------------------------------
// Sidebar (desktop only — hidden below sm)
// ---------------------------------------------------------------------------
function Sidebar({
  items,
  username,
}: {
  items: NavItem[];
  username: string | null;
}) {
  const pathname = usePathname();
  const activeKey = pickActiveNavKey(items, pathname);

  return (
    <aside className="hidden sm:flex fixed left-0 top-0 bottom-0 z-40 w-56 flex-col border-r border-border bg-sidebar">
      {/* Bot name / brand — clickable, returns to the dashboard. */}
      <Link
        href="/"
        aria-label="Go to dashboard"
        className="flex h-14 items-center gap-2 px-4 border-b border-sidebar-border shrink-0 hover:bg-sidebar-accent/40 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset"
      >
        <span
          aria-hidden
          className="flex size-6 items-center justify-center rounded-md bg-primary text-[10px] font-bold uppercase text-primary-foreground"
        >
          cm
        </span>
        <span className="text-sm font-semibold tracking-tight text-sidebar-foreground">
          WhatsApp Bot
        </span>
      </Link>

      {/* Nav items */}
      <nav aria-label="Primary navigation" className="flex flex-col gap-1 p-3 flex-1">
        {items.map(({ key, href, label, icon: Icon }) => {
          const active = href === "/" ? pathname === "/" : pathname.startsWith(href);
          return (
            <Link
              key={key}
              // eslint-disable-next-line @typescript-eslint/no-explicit-any
              href={href as any}
              aria-current={active ? "page" : undefined}
              className={cn(
                "flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors min-h-[44px]",
                active
                  ? "bg-sidebar-accent text-sidebar-accent-foreground"
                  : "text-sidebar-foreground hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground",
              )}
            >
              <Icon size={18} strokeWidth={active ? 2.5 : 1.75} aria-hidden />
              {label}
            </Link>
          );
        })}
      </nav>

      {/* Footer: signed-in user + sign-out */}
      <div className="border-t border-sidebar-border p-3">
        <SignOutButton username={username} />
      </div>
    </aside>
  );
}

// ---------------------------------------------------------------------------
// Bare header for unauthenticated routes (/login). No sidebar, no mobile
// menu, no nav — just the centered brand mark + name. The user explicitly
// asked for nothing else here so the sign-in screen feels like a separate
// surface from the authenticated app.
// ---------------------------------------------------------------------------
function BareHeader() {
  return (
    <header className="fixed top-0 left-0 right-0 z-40 flex h-14 items-center justify-center border-b border-border bg-background/95 backdrop-blur-sm px-3">
      <div className="flex items-center gap-2">
        <span
          aria-hidden
          className="flex size-6 items-center justify-center rounded-md bg-primary text-[10px] font-bold uppercase text-primary-foreground"
        >
          cm
        </span>
        <span className="text-sm font-semibold tracking-tight">
          WhatsApp Bot
        </span>
      </div>
    </header>
  );
}

// ---------------------------------------------------------------------------
// AppShell — the outer container
// ---------------------------------------------------------------------------
interface AppShellProps {
  children: React.ReactNode;
  /** Role of the signed-in user, or null when unauthenticated. */
  role: NavRole | null;
  /** Username of the signed-in user, surfaced in the footer + sign-out hint. */
  username: string | null;
}

export function AppShell({ children, role, username }: AppShellProps) {
  const pathname = usePathname();
  const isAuthRoute = pathname === "/login";

  if (isAuthRoute) {
    return (
      <>
        <BareHeader />
        <main className="min-h-dvh pt-14">{children}</main>
      </>
    );
  }

  // Treat unauthenticated render of a protected route (shouldn't happen
  // because middleware redirects, but defense-in-depth) as 'user': hides
  // the admin-only entries.
  const items = navItemsForRole(role ?? "user");

  return (
    <>
      {/* Desktop sidebar */}
      <Sidebar items={items} username={username} />

      {/* Mobile header (single row: brand · title · menu) */}
      <MobileHeader items={items} username={username} />

      {/* Main content
          Mobile:  push down for the h-14 header (56px) plus a small gap
          so page titles don't kiss the bottom edge of the nav.
          Desktop: push right for the sidebar (sm:pl-56), no top offset. */}
      <main className="min-h-dvh pt-16 sm:pl-56 sm:pt-0">
        {children}
      </main>
    </>
  );
}
