import { create } from "zustand";
import { authApi } from "../../shared/api/endpoints";
import { tokenStorage } from "../../shared/api/client";

function readStoredUser() {
  try {
    return JSON.parse(sessionStorage.getItem("user") ?? "null");
  } catch {
    return null;
  }
}

function persistUser(user) {
  if (user) sessionStorage.setItem("user", JSON.stringify(user));
  else sessionStorage.removeItem("user");
}

function getToken(payload) {
  return payload?.accessToken ?? payload?.token ?? payload?.jwt;
}

function getUser(payload) {
  return payload?.user ?? payload?.profile ?? payload;
}

export const useSession = create((set, get) => ({
  user: readStoredUser(),
  initializing: false,

  register: async (payload) => {
    const response = await authApi.register(payload);
    const token = getToken(response);
    const user = getUser(response);
    tokenStorage.set(token);
    set({ user });
    persistUser(user);
    return user;
  },

  login: async ({ email, password }) => {
    const response = await authApi.login({ email, password });
    const token = getToken(response);
    tokenStorage.set(token);

    const user = response.user ?? (await authApi.me());
    set({ user });
    persistUser(user);
    return user;
  },

  loadMe: async () => {
    if (!tokenStorage.get()) return get().user;

    set({ initializing: true });
    try {
      const user = await authApi.me();
      set({ user, initializing: false });
      persistUser(user);
      return user;
    } catch (error) {
      set({ user: null, initializing: false });
      persistUser(null);
      throw error;
    }
  },

  logout: async () => {
    if (tokenStorage.get()) {
      try {
        await authApi.logout();
      } catch {
        // The local session still must be cleared if backend logout fails.
      }
    }

    tokenStorage.clear();
    persistUser(null);
    set({ user: null });
  },

  changePassword: (payload) => authApi.changePassword(payload),

  updateUser: (patch) => {
    const user = { ...get().user, ...patch };
    set({ user });
    persistUser(user);
    return user;
  },

  switchRole: () => get().user,
}));

if (typeof window !== "undefined") {
  window.addEventListener("auth:unauthorized", () => {
    persistUser(null);
    useSession.setState({ user: null });
  });
}
