import React, { createContext, useState, useContext, useEffect } from "react";
import { GoogleOAuthProvider } from "@react-oauth/google";
import { usePathname } from "next/navigation";
import { useRouter } from "next/router";
import { TokenResponse, Tokens } from "..";
import { logoutApi } from "../utils/hooks/useLogout";

export const AuthContext = createContext({});

interface Auth {
  isAuthenticated: boolean;
  token: {
    success: boolean;
    token: string;
    message: string;
  };
  logout: () => Promise<boolean>;
  setTokenCookie: (tokens: any) => any;
  loading: boolean;
}

export const AuthProvider = ({ children }: any) => {
  const router = useRouter();
  const [token, setToken] = useState<Tokens | null>(null);
  const [tokenChecked, setTokenChecked] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    (async function () {
      const token = (await getTokenCookie()) as Tokens;
      if (token?.jwtToken) {
        setToken({
          jwtToken: token.jwtToken,
          refreshToken: token.refreshToken,
          name: token.name,
          profileType: token.profileType,
        });
      }
      setLoading(false);
      setTokenChecked(true);
    })();
  }, []);

  // ✅ Set cookie and redirect after login
  const setTokenCookie = async (tokens: Tokens) => {
    const { jwtToken, refreshToken, name, profileType, referrer } = tokens;

    return new Promise(async (resolve, reject) => {
      try {
        // Save to localStorage
        localStorage.setItem("refreshToken", refreshToken);
        localStorage.setItem("jwtToken", jwtToken);
        localStorage.setItem("jobratorName", name);
        localStorage.setItem("profileType", profileType);

        // Refresh token state
        const token = (await getTokenCookie()) as TokenResponse;

        // ✅ List of invalid referrers (to prevent looping redirects)
        const invalidReferrers = [
          "/",
          "/login",
          "/logout",
          "/forget-password",
          "/reset-password",
        ];

        // ✅ Decide where to redirect after login
        if (referrer && !invalidReferrers.includes(referrer)) {
          router.push(referrer);
        } else {
          if (profileType === "Candidate") {
            router.push("/jobs");
          } else if (profileType === "Company") {
            router.push("/dashboard");
          } else {
            router.push("/"); // fallback
          }
        }

        // ✅ Update token state
        if (token?.jwtToken) {
          setToken({
            jwtToken,
            refreshToken,
            name,
            profileType,
          });
        }

        setLoading(false);
        setTokenChecked(true);
        resolve("Successfully Logged in");
      } catch (e) {
        reject("Error Setting item to localStorage");
        console.error(e);
      }
    });
  };

  // ✅ Retrieve tokens from localStorage
  const getTokenCookie = () => {
    return new Promise(async (resolve, reject) => {
      try {
        const jwtToken = localStorage.getItem("jwtToken") as string;
        const refreshToken = localStorage.getItem("refreshToken") as string;
        const name = localStorage.getItem("jobratorName") as string;
        const profileType = localStorage.getItem("profileType") as string;
        resolve({ jwtToken, refreshToken, name, profileType });
      } catch (e) {
        reject("Can't Get Token from Local Storage");
        console.error(e);
      }
    });
  };

  // Logout
  const logout = React.useCallback(async () => {
    // Backend logout is best-effort only; local logout must always complete.
    await logoutApi();

    setToken({
      jwtToken: "",
      refreshToken: "",
      name: "",
      profileType: "",
    });
    localStorage.removeItem("jwtToken");
    localStorage.removeItem("refreshToken");
    localStorage.removeItem("jobratorName");
    localStorage.removeItem("profileType");

    return true;
  }, []);

  return (
    <GoogleOAuthProvider clientId={process.env.NEXT_PUBLIC_CLIENT_ID!}>
      <AuthContext.Provider
        value={{
          isAuthenticated: !!token?.jwtToken,
          token: token?.jwtToken,
          name: token?.name,
          loading,
          setTokenCookie,
          logout,
          userRole: token?.profileType,
        }}
      >
        {tokenChecked ? children : null}
      </AuthContext.Provider>
    </GoogleOAuthProvider>
  );
};

// Custom hook for easier access
export const useAuth = (): Auth => useContext(AuthContext) as Auth;

// Route protection component
export const ProtectRoute = ({ children }: any) => {
  const { isAuthenticated, loading } = useAuth() as Auth;
  const currentPath = usePathname();
  const router = useRouter();

  if (currentPath) {
    // Public routes that don’t require authentication
    const publicRoutes = [
      "/",
      "/login",
      "/logout",
      "/jobs",
      "/register",
      "/about",
      "/subscription",
      "/subscription-details-page",
      "/contact-us",
      "/forget-password",
      "/reset-password",
      "/privacy-policies",
      "/terms-and-conditions",
      "/cookie-policy",
      "/faq",
      "/about-us",
      "/resources",
      "/guide/how-to-add-guarantors",
    ];

    // Check access rules
    const isPublicRoute =
      publicRoutes.includes(currentPath) ||
      currentPath.startsWith("/jobs/") ||
      currentPath.startsWith("/resources/") ||
      currentPath.startsWith("/guarantor-verification");

    if (!isAuthenticated && !isPublicRoute) {
      router.push("/login");
      console.log("Redirected to /login (unauthenticated user)");
    } else if (isAuthenticated && currentPath === "/register") {
      router.push("/dashboard");
      return null;
    } else if (
      isAuthenticated &&
      localStorage.profileType === "Candidate" &&
      currentPath === "/dashboard/post-jobs"
    ) {
      router.push("/error-page");
    } else if (
      isAuthenticated &&
      localStorage.profileType === "Candidate" &&
      [
        "/dashboard/all-applicants",
        "/dashboard/shortlisted-resumes",
        "/dashboard/post-jobs",
        "/dashboard/manage-jobs",
        "/dashboard/company-profile",
        "/dashboard/company-packages",
        "/dashboard/resume-alerts",
      ].some(
        (path) => currentPath === path || currentPath.startsWith(`${path}/`),
      )
    ) {
      router.push("/error-page");
    } else if (!loading) {
      return children;
    }
  }
};
