import { createSlice, type PayloadAction } from "@reduxjs/toolkit";
import type {
  AuthState,
  AuthUser,
  CurrentProfile,
  LoginPayload,
} from "../types/auth.types";
import { authStorage } from "../utils/auth-storage";
import { setSignedOut } from "../utils/refresh-token";

const initialState: AuthState = {
  user: null,
  token: null,
  isAuthenticated: false,
  currentProfile: null,
};

const authSlice = createSlice({
  name: "auth",
  initialState,
  reducers: {
    loginSuccess(state, action: PayloadAction<LoginPayload>) {
      setSignedOut(false);
      state.token = action.payload.token;
      state.isAuthenticated = true;
      authStorage.setToken(action.payload.token);
      authStorage.setRefreshToken(action.payload.refreshToken);
    },
    setUser(state, action: PayloadAction<AuthUser>) {
      state.user = action.payload;
      authStorage.setUser(action.payload);
    },
    setCurrentProfile(state, action: PayloadAction<CurrentProfile>) {
      state.currentProfile = action.payload;
      authStorage.setProfile(action.payload);
    },
    clearCurrentProfile(state) {
      state.currentProfile = null;
      authStorage.removeProfile();
    },
    logout(state) {
      // Before clearing storage, so an in-flight refresh can't repopulate it.
      setSignedOut(true);
      state.user = null;
      state.token = null;
      state.isAuthenticated = false;
      state.currentProfile = null;
      authStorage.clear();
    },
    setToken(state, action: PayloadAction<string>) {
      state.token = action.payload;
      authStorage.setToken(action.payload);
    },
    hydrateAuth(state) {
      const token = authStorage.getToken();
      const user = authStorage.getUser<AuthUser>();
      const profile = authStorage.getProfile<CurrentProfile>();
      if (token && user) {
        state.token = token;
        state.user = user;
        state.isAuthenticated = true;
        if (profile) {
          state.currentProfile = profile;
        }
      }
    },
  },
});

export const {
  loginSuccess,
  setUser,
  setCurrentProfile,
  clearCurrentProfile,
  logout,
  hydrateAuth,
  setToken,
} = authSlice.actions;
export const authReducer = authSlice.reducer;
