"use client";

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

import { clearCmsSession, getCmsApiBaseUrl } from "@/lib/api-base";

type Props = {
  children: ReactNode;
};

export default function AuthGate({ children }: Props) {
  const router = useRouter();
  const [loading, setLoading] = useState(true);

  const apiBaseUrl = getCmsApiBaseUrl();
  const accessTokenKey = "accessToken";

  useEffect(() => {
    let isMounted = true;

    const getToken = () => localStorage.getItem(accessTokenKey);
    const clearAndRedirect = () => {
      clearCmsSession();
      router.replace("/login");
    };

    const fetchMe = async (token: string) => {
      const meRes = await fetch(`${apiBaseUrl}/auth/me`, {
        method: "GET",
        headers: { Authorization: `Bearer ${token}` },
      });

      if (meRes.status === 401) {
        // Phase 1 polish: attempt refresh once, then retry /auth/me.
        const refreshRes = await fetch(`${apiBaseUrl}/auth/refresh`, {
          method: "POST",
          credentials: "include",
        });
        if (!refreshRes.ok) {
          throw new Error("REFRESH_FAILED");
        }

        const refreshData = (await refreshRes.json().catch(() => null)) as { accessToken?: string } | null;
        if (!refreshData?.accessToken) {
          throw new Error("REFRESH_FAILED");
        }

        localStorage.setItem(accessTokenKey, refreshData.accessToken);

        const retryMeRes = await fetch(`${apiBaseUrl}/auth/me`, {
          method: "GET",
          headers: { Authorization: `Bearer ${refreshData.accessToken}` },
        });
        if (!retryMeRes.ok) {
          throw new Error("ME_FAILED");
        }

        const retryMeData = await retryMeRes.json();
        localStorage.setItem("authUser", JSON.stringify(retryMeData?.user ?? null));
        return;
      }

      if (!meRes.ok) {
        throw new Error("ME_FAILED");
      }

      const meData = await meRes.json();
      localStorage.setItem("authUser", JSON.stringify(meData?.user ?? null));
    };

    const token = getToken();
    if (!token) {
      clearAndRedirect();
      return;
    }

    fetchMe(token)
      .then(() => {
        if (!isMounted) return;
        setLoading(false);
      })
      .catch(() => {
        if (!isMounted) return;
        clearAndRedirect();
      });

    return () => {
      isMounted = false;
    };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps -- validate session once per mount

  if (loading) {
    return (
      <div className="min-h-screen flex items-center justify-center">
        <div className="text-gray-600">Loading...</div>
      </div>
    );
  }

  return <>{children}</>;
}

