import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import {
  clearAuthStorage,
  getStoredAdminProfile,
  getStoredToken,
  setStoredAdminProfile,
  setStoredToken,
} from "@/utils/storage";
import { isTokenValid } from "@/utils/decodeToken";

export type AdminRole = "super_admin" | "admin";

export interface AdminProfile {
  id: number;
  fullname: string;
  email: string;
  role: AdminRole;
  is_email_verified: boolean;
  is_active: boolean;
  last_login_at?: string | null;
}

interface AuthState {
  token: string | null;
  admin: AdminProfile | null;
  isAuthenticated: boolean;
  /** True until we have attempted to hydrate from localStorage / server. */
  isInitializing: boolean;
}

function hydrate(): AuthState {
  const token = getStoredToken();
  if (token && isTokenValid(token)) {
    return {
      token,
      admin: getStoredAdminProfile<AdminProfile>(),
      isAuthenticated: true,
      isInitializing: true,
    };
  }
  return {
    token: null,
    admin: null,
    isAuthenticated: false,
    isInitializing: true,
  };
}

const initialState: AuthState = {
  token: null,
  admin: null,
  isAuthenticated: false,
  isInitializing: true,
};

const authSlice = createSlice({
  name: "auth",
  initialState,
  reducers: {
    /** Replace state with values from localStorage. Call once on the client. */
    hydrateFromStorage: (state) => {
      const next = hydrate();
      state.token = next.token;
      state.admin = next.admin;
      state.isAuthenticated = next.isAuthenticated;
      state.isInitializing = false;
    },
    setCredentials: (
      state,
      action: PayloadAction<{ token: string; admin: AdminProfile }>,
    ) => {
      state.token = action.payload.token;
      state.admin = action.payload.admin;
      state.isAuthenticated = true;
      state.isInitializing = false;
      setStoredToken(action.payload.token);
      setStoredAdminProfile(action.payload.admin);
    },
    setAdmin: (state, action: PayloadAction<AdminProfile>) => {
      state.admin = action.payload;
      setStoredAdminProfile(action.payload);
    },
    markInitialized: (state) => {
      state.isInitializing = false;
    },
    logout: (state) => {
      state.token = null;
      state.admin = null;
      state.isAuthenticated = false;
      state.isInitializing = false;
      clearAuthStorage();
    },
  },
});

export const { hydrateFromStorage, setCredentials, setAdmin, markInitialized, logout } =
  authSlice.actions;
export default authSlice.reducer;
