"use client";

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

import type { AuthSession } from "@rental/shared";

import { clearStoredSession, readStoredSession, saveStoredSession, sessionSyncEventName } from "../../lib/api";

type SessionContextValue = {
  session: AuthSession | null;
  ready: boolean;
  setSession: (session: AuthSession | null) => void;
};

const SessionContext = createContext<SessionContextValue | undefined>(undefined);

export const SessionProvider = ({ children }: { children: React.ReactNode }) => {
  const [session, setSessionState] = useState<AuthSession | null>(null);
  const [ready, setReady] = useState(false);

  useEffect(() => {
    setSessionState(readStoredSession());
    setReady(true);
  }, []);

  useEffect(() => {
    const syncSessionState = () => {
      setSessionState(readStoredSession());
    };

    window.addEventListener("storage", syncSessionState);
    window.addEventListener(sessionSyncEventName, syncSessionState);

    return () => {
      window.removeEventListener("storage", syncSessionState);
      window.removeEventListener(sessionSyncEventName, syncSessionState);
    };
  }, []);

  const setSession = (nextSession: AuthSession | null) => {
    setSessionState(nextSession);

    if (nextSession) {
      saveStoredSession(nextSession);
      return;
    }

    clearStoredSession();
  };

  return <SessionContext.Provider value={{ session, ready, setSession }}>{children}</SessionContext.Provider>;
};

export const useSessionContext = () => {
  const context = useContext(SessionContext);

  if (!context) {
    throw new Error("useSessionContext must be used within SessionProvider");
  }

  return context;
};
