"use client";

import { usePathname, useRouter } from "next/navigation";
import { useState, useEffect, useLayoutEffect, useRef } from "react";
import { ROUTES, EachRoute } from "@/lib/routes";
import { cn } from "@/lib/utils";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
import * as LucideIcons from "lucide-react";
import { ChevronsUpDown, Check, type LucideIcon } from "lucide-react";
import { Skeleton } from "@/components/ui/skeleton";

interface ContextPopoverProps {
  className?: string;
}

// Get all root-level routes with context
function getContextRoutes(): EachRoute[] {
  return ROUTES.filter(route => route.context);
}

// Get the first item's href from a route
function getFirstItemHref(route: EachRoute): string {
  return route.items?.[0]?.href ? `${route.href}${route.items[0].href}` : route.href;
}

// Get the active context route from the current path
function getActiveContextRoute(path: string): EachRoute | undefined {
  if (!path.startsWith('/docs')) return undefined;
  const docPath = path.replace(/^\/docs/, '');
  return getContextRoutes().find(route => docPath.startsWith(route.href));
}

// Get icon component by name
function getIcon(name: string) {
  const Icon = LucideIcons[name as keyof typeof LucideIcons] as LucideIcon | undefined;
  if (!Icon) return <LucideIcons.FileQuestion className="h-4 w-4" />;
  return <Icon className="h-4 w-4" />;
}

export default function ContextPopover({ className }: ContextPopoverProps) {
  const pathname = usePathname();
  const router = useRouter();
  const [mounted, setMounted] = useState(false);
  const [activeRoute, setActiveRoute] = useState<EachRoute>();
  const [useDefaultTitle, setUseDefaultTitle] = useState(false);
  const [triggerWidth, setTriggerWidth] = useState<number | null>(null);
  const triggerRef = useRef<HTMLButtonElement>(null);
  const contextRoutes = getContextRoutes();
  const fallbackRoute = ROUTES[0];
  const displayRoute = useDefaultTitle ? fallbackRoute : activeRoute;

  useEffect(() => {
    // Mount-only state (used for client-only rendering) and intentionally set after first render.
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setMounted(true);
  }, []);

  useEffect(() => {
    if (pathname.startsWith("/docs")) {
      // eslint-disable-next-line react-hooks/set-state-in-effect
      setActiveRoute(getActiveContextRoute(pathname));
    } else {
      setActiveRoute(undefined);
    }
  }, [pathname]);

  useEffect(() => {
    const hasTitle = Boolean(
      activeRoute?.context?.title ||
      activeRoute?.title
    );

    if (!hasTitle) {
      const timer = window.setTimeout(() => {
        setUseDefaultTitle(true);
      }, 300);

      return () => window.clearTimeout(timer);
    }

    // Avoid calling setState synchronously inside the effect body.
    // Using a micro task to reset state avoids the react-hooks/set-state-in-effect lint error.
    const resetTimer = window.setTimeout(() => {
      setUseDefaultTitle(false);
    }, 0);

    return () => window.clearTimeout(resetTimer);
  }, [activeRoute?.context?.title, activeRoute?.title]);

  // Keep the popover width in sync with the trigger width when the trigger text changes
  // (e.g. when navigating between docs contexts) and when the window/resizing changes.
  useLayoutEffect(() => {
    if (!triggerRef.current) return;

    const updateWidth = () => {
      if (triggerRef.current) {
        setTriggerWidth(triggerRef.current.offsetWidth);
      }
    };

    // Make sure the width is updated when the trigger text/route changes.
    updateWidth();

    if (typeof ResizeObserver !== "undefined") {
      const observer = new ResizeObserver(() => {
        updateWidth();
      });
      observer.observe(triggerRef.current);

      return () => {
        observer.disconnect();
      };
    } else {
      const handleResize = () => {
        updateWidth();
      };

      window.addEventListener("resize", handleResize);

      return () => {
        window.removeEventListener("resize", handleResize);
      };
    }
  }, [displayRoute]);

  if (!mounted || !pathname.startsWith("/docs") || contextRoutes.length === 0) {
    return null;
  }

  return (
    <Popover>
      <PopoverTrigger asChild>
        <Button
          ref={triggerRef}
          variant="ghost"
          className={cn(
            "w-full cursor-pointer flex items-center justify-between font-semibold text-foreground px-2 py-4 border border-muted",
            "hover:bg-transparent hover:text-foreground",
            className
          )}
        >
          <div className="flex items-center gap-2">
            {displayRoute?.context?.icon && (
              <span className="text-primary bg-primary/10 border border-primary dark:border dark:border-accent dark:bg-accent/10 dark:text-accent rounded p-0.5">
                {getIcon(displayRoute.context.icon)}
              </span>
            )}
            <span className="truncate text-sm">
              {displayRoute?.context?.title ||
                displayRoute?.title ||
                (useDefaultTitle
                  ? fallbackRoute?.context?.title || fallbackRoute?.title
                  : <Skeleton className="h-3.5 w-24" />)}
            </span>
          </div>
          <ChevronsUpDown className="h-4 w-4 text-foreground/50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="p-2"
        align="start"
        sideOffset={6}
        style={{
          width: triggerWidth !== null ? `${triggerWidth}px` : "auto"
        }}
      >
        <div className="space-y-1">
          {contextRoutes.map((route) => {
            const isActive = activeRoute?.href === route.href;
            const firstItemPath = getFirstItemHref(route);
            const contextPath = `/docs${firstItemPath}`;

            return (
              <button
                key={route.href}
                onClick={() => router.push(contextPath)}
                className={cn(
                  "relative flex w-full items-center gap-2 cursor-pointer rounded px-2 py-1.5 text-sm",
                  "text-left outline-none transition-colors",
                  isActive
                    ? "bg-primary/20 text-primary dark:bg-accent/20 dark:text-accent"
                    : "text-foreground/80 hover:bg-primary/20 dark:text-foreground/60 dark:hover:bg-accent/20"
                )}
              >
                {route.context?.icon && (
                  <span className={cn(
                    "flex h-4 w-4 items-center justify-center",
                    isActive ? "text-primary dark:text-accent" : "text-foreground/60"
                  )}>
                    {getIcon(route.context.icon)}
                  </span>
                )}
                <div className="flex-1 min-w-0 overflow-hidden">
                  <div className="truncate font-medium">
                    {route.context?.title || route.title}
                  </div>
                  {route.context?.description && (
                    <div className="text-xs text-muted-foreground truncate text-ellipsis overflow-hidden max-w-full">
                      {route.context.description}
                    </div>
                  )}
                </div>
                {isActive && (
                  <Check className="h-3.5 w-3.5" />
                )}
              </button>
            );
          })}
        </div>
      </PopoverContent>
    </Popover>
  );
}
