"use client";

import * as React from "react";
import { usePathname, useSearchParams } from "next/navigation";
import { cn } from "@/lib/utils";

/**
 * Slim progress bar at the very top of the viewport. It starts when the user
 * clicks an internal link and completes when the App Router commits the new
 * route, so every page switch has a visible, immediate response.
 */
function Bar() {
  const pathname = usePathname();
  const search = useSearchParams();
  const route = `${pathname}?${search.toString()}`;
  const [phase, setPhase] = React.useState<"idle" | "loading" | "done">("idle");
  const started = React.useRef<string | null>(null);

  React.useEffect(() => {
    if (phase !== "loading" || started.current === route) return;
    setPhase("done");
    const t = setTimeout(() => setPhase("idle"), 320);
    return () => clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [route]);

  React.useEffect(() => {
    const onClick = (e: MouseEvent) => {
      if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
      const a = (e.target as Element | null)?.closest?.("a[href]") as HTMLAnchorElement | null;
      if (!a || a.target === "_blank" || a.hasAttribute("download")) return;
      let url: URL;
      try {
        url = new URL(a.href, location.href);
      } catch {
        return;
      }
      if (url.origin !== location.origin || url.hash) return;
      const next = `${url.pathname}?${url.searchParams.toString()}`;
      const here = `${location.pathname}?${new URLSearchParams(location.search).toString()}`;
      if (next === here) return;
      started.current = here;
      setPhase("loading");
    };
    document.addEventListener("click", onClick, true);
    return () => document.removeEventListener("click", onClick, true);
  }, []);

  React.useEffect(() => {
    if (phase !== "loading") return;
    const t = setTimeout(() => setPhase("idle"), 10_000);
    return () => clearTimeout(t);
  }, [phase]);

  if (phase === "idle") return null;
  return (
    <div className="pointer-events-none fixed inset-x-0 top-0 z-[90] h-[2.5px]" aria-hidden>
      <div className={cn("route-bar h-full rounded-r-full", phase === "loading" ? "animate-route-progress" : "w-full opacity-0 transition-opacity duration-300")} />
    </div>
  );
}

export function RouteProgress() {
  return (
    <React.Suspense fallback={null}>
      <Bar />
    </React.Suspense>
  );
}
