"use client";

import { usePathname } from "next/navigation";
import { useEffect, useRef, useState } from "react";

function isInternalNavigation(anchor: HTMLAnchorElement): boolean {
  const href = anchor.getAttribute("href");
  if (!href || href.startsWith("#")) return false;
  if (anchor.target && anchor.target !== "_self") return false;
  if (anchor.hasAttribute("download")) return false;

  const url = new URL(href, window.location.href);
  if (url.origin !== window.location.origin) return false;

  const current = `${window.location.pathname}${window.location.search}`;
  const next = `${url.pathname}${url.search}`;
  return current !== next;
}

export function GlobalRouteLoading(props: { children: React.ReactNode }) {
  const pathname = usePathname();
  const [isRouting, setIsRouting] = useState(false);
  const lastPathRef = useRef(pathname);

  useEffect(() => {
    const onClickCapture = (event: MouseEvent) => {
      if (event.defaultPrevented || event.button !== 0) return;
      if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;

      const target = event.target as HTMLElement | null;
      const anchor = target?.closest("a");
      if (!anchor) return;

      if (isInternalNavigation(anchor)) {
        setIsRouting(true);
      }
    };

    document.addEventListener("click", onClickCapture, true);
    return () => document.removeEventListener("click", onClickCapture, true);
  }, []);

  useEffect(() => {
    if (pathname !== lastPathRef.current) {
      lastPathRef.current = pathname;
      const timer = window.setTimeout(() => setIsRouting(false), 220);
      return () => window.clearTimeout(timer);
    }
    return;
  }, [pathname]);

  return (
    <>
      {props.children}
      {isRouting ? (
        <div className="global-route-loading" role="status" aria-live="polite" aria-label="页面加载中">
          <div className="global-route-loading__card">
            <div className="global-route-loading__spinner" />
            <p>页面加载中...</p>
          </div>
        </div>
      ) : null}
    </>
  );
}

