import { configureStore, combineReducers } from '@reduxjs/toolkit';
import {
  persistStore,
  persistReducer,
  createTransform,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
  type PersistConfig,
} from 'redux-persist';
import createWebStorage from 'redux-persist/lib/storage/createWebStorage';
import { STORAGE_KEYS } from '@/constants';
import type { AuthState, User } from '@/types';
import authReducer from './slices/authSlice';
import subscriptionReducer from './slices/subscriptionSlice';
import paymentReducer from './slices/paymentSlice';
import uiReducer from './slices/uiSlice';
import themeReducer from './slices/themeSlice';

const createNoopStorage = () => ({
  getItem: () => Promise.resolve(null),
  setItem: (_key: string, value: string) => Promise.resolve(value),
  removeItem: () => Promise.resolve(),
});

const storage =
  typeof window !== 'undefined' ? createWebStorage('local') : createNoopStorage();

const authTransform = createTransform(
  (inbound: AuthState) => {
    if (!inbound.user) return { user: null, isAuthenticated: false };
    const { access_token, ...userWithoutToken } = inbound.user;
    return { user: userWithoutToken, isAuthenticated: inbound.isAuthenticated };
  },
  (outbound: { user: Omit<User, 'access_token'> | null; isAuthenticated: boolean }) => ({
    user: outbound.user ?? null,
    isAuthenticated: outbound.isAuthenticated,
    isLoading: false,
    error: null,
  }),
  { whitelist: ['auth'] },
);

const rootReducer = combineReducers({
  auth: authReducer,
  subscription: subscriptionReducer,
  payment: paymentReducer,
  ui: uiReducer,
  theme: themeReducer,
});

type RootReducerState = ReturnType<typeof rootReducer>;

const persistConfig: PersistConfig<RootReducerState> = {
  key: STORAGE_KEYS.REDUX_PERSIST,
  storage,
  whitelist: ['auth', 'theme'],
  transforms: [authTransform],
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

export const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
  devTools: process.env.NODE_ENV !== 'production',
});

export const persistor = persistStore(store);

export type RootState = ReturnType<typeof rootReducer>;
export type AppDispatch = typeof store.dispatch;
