import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState
} from "react";

import {
  clearAdminSession,
  getAdminToken,
  getCurrentAdmin,
  getStoredAdmin,
  loginAdmin,
  logoutAdmin,
  storeAdminSession
} from "../services/adminAuthService";

const AdminAuthContext =
  createContext(null);

export const AdminAuthProvider = ({
  children
}) => {
  const [
    admin,
    setAdmin
  ] = useState(
    getStoredAdmin
  );

  const [
    loading,
    setLoading
  ] = useState(true);

  const clearSession =
    useCallback(() => {
      clearAdminSession();
      setAdmin(null);
    }, []);

  const verifySession =
    useCallback(
      async () => {
        const accessToken =
          getAdminToken();

        if (!accessToken) {
          clearSession();
          setLoading(false);
          return;
        }

        try {
          const result =
            await getCurrentAdmin();

          const currentAdmin =
            result?.data?.admin;

          if (!currentAdmin) {
            clearSession();
            return;
          }

          setAdmin(
            currentAdmin
          );

          sessionStorage.setItem(
            "adminUser",
            JSON.stringify(
              currentAdmin
            )
          );
        } catch (error) {
          console.error(
            "Admin session verification error:",
            error
          );

          clearSession();
        } finally {
          setLoading(false);
        }
      },
      [
        clearSession
      ]
    );

  useEffect(() => {
    verifySession();
  }, [verifySession]);

  const login =
    async ({
      identifier,
      password
    }) => {
      const result =
        await loginAdmin({
          identifier,
          password
        });

      const accessToken =
        result?.data
          ?.access_token;

      const loggedInAdmin =
        result?.data?.admin;

      if (
        !accessToken ||
        !loggedInAdmin
      ) {
        throw new Error(
          "The administrator login response was incomplete."
        );
      }

      storeAdminSession({
        accessToken,
        admin:
          loggedInAdmin
      });

      setAdmin(
        loggedInAdmin
      );

      return result;
    };

  const logout =
    async () => {
      try {
        if (getAdminToken()) {
          await logoutAdmin();
        }
      } catch (error) {
        console.error(
          "Admin logout error:",
          error
        );
      } finally {
        clearSession();
      }
    };

  const contextValue =
    useMemo(
      () => ({
        admin,

        loading,

        isAuthenticated:
          Boolean(admin),

        login,

        logout,

        verifySession,

        clearSession
      }),
      [
        admin,
        loading,
        verifySession,
        clearSession
      ]
    );

  return (
    <AdminAuthContext.Provider
      value={contextValue}
    >
      {children}
    </AdminAuthContext.Provider>
  );
};

export const useAdminAuth =
  () => {
    const context =
      useContext(
        AdminAuthContext
      );

    if (!context) {
      throw new Error(
        "useAdminAuth must be used inside AdminAuthProvider."
      );
    }

    return context;
  };