"use client";

import type { ReactNode } from "react";
import { useEffect, useState } from "react";
import { usePathname, useRouter } from "next/navigation";

import { safeNextUrl } from "@/lib/auth-navigation";
import { getAccessToken, getMe, type MeUser } from "@/lib/web-auth-client";

type Props = {
  children: ReactNode;
};

/** Logged-in users may open these paths before phone OTP; API routes still enforce PhoneVerifiedGuard. */
const PATHS_ALLOWING_UNVERIFIED_PHONE = ["/account"] as const;

/**
 * Exact match or one segment deeper under `prefix` (e.g. `/account/settings`).
 * If `prefix` is `/`, only an exact `/` matches — never treat every URL as “under /”.
 */
function pathnameMatchesAllowedPrefix(pathname: string, prefix: string): boolean {
  if (pathname === prefix) return true;
  if (prefix === "/") return false;
  return pathname.startsWith(`${prefix}/`);
}

function pathAllowsUnverifiedPhone(pathname: string | null): boolean {
  const p = pathname ?? "";
  return PATHS_ALLOWING_UNVERIFIED_PHONE.some((allowed) => pathnameMatchesAllowedPrefix(p, allowed));
}

/**
 * Client gate for protected pages (not applied globally yet).
 * Redirects unauthenticated users to /login; unverified phone to /verify-phone,
 * except on paths in PATHS_ALLOWING_UNVERIFIED_PHONE (e.g. /account: profile + gate-test UI).
 * Backend PhoneVerifiedGuard is unchanged — /auth/account-gate-test stays 403 until OTP verified.
 */
export function RequireAuth({ children }: Props) {
  const router = useRouter();
  const pathname = usePathname();
  const [state, setState] = useState<"loading" | "ready" | "redirecting">("loading");
  const [user, setUser] = useState<MeUser | null>(null);

  useEffect(() => {
    let cancelled = false;

    async function run() {
      const token = getAccessToken();
      if (!token) {
        const next = safeNextUrl(pathname || "/");
        router.replace(`/login?next=${encodeURIComponent(next)}`);
        if (!cancelled) setState("redirecting");
        return;
      }

      try {
        const { user: u } = await getMe();
        if (cancelled) return;
        const onVerifyRoute =
          (pathname ?? "") === "/verify-phone" || (pathname ?? "").startsWith("/verify-phone/");
        const allowUnverifiedHere = pathAllowsUnverifiedPhone(pathname);
        if (u.requiresPhoneVerification && !onVerifyRoute && !allowUnverifiedHere) {
          const next = safeNextUrl(pathname || "/");
          router.replace(`/verify-phone?next=${encodeURIComponent(next)}`);
          setState("redirecting");
          return;
        }
        setUser(u);
        setState("ready");
      } catch {
        if (cancelled) return;
        const next = safeNextUrl(pathname || "/");
        router.replace(`/login?next=${encodeURIComponent(next)}`);
        setState("redirecting");
      }
    }

    void run();
    return () => {
      cancelled = true;
    };
  }, [pathname, router]);

  if (state !== "ready" || !user) {
    return (
      <div className="mx-auto max-w-[1100px] flex-1 px-4 py-20 text-center text-sm text-stone-500">
        Đang kiểm tra phiên đăng nhập…
      </div>
    );
  }

  return <>{children}</>;
}
