import {
  applyMiddleware,
  Reducer,
  Store,
  PreloadedState,
  AnyAction,
  legacy_createStore,
  compose,
} from "redux";
import createSagaMiddleware from "redux-saga";

import {
  defaultSaga,
  ApiAdapterException,
} from "@dndbeyond/character-rules-engine/es";

import { rollResultSaga } from "../sagas";
import { AppLoggerUtils } from "../utils";

let store: Store | null = null;

export function getAppStore(): Store | null {
  return store;
}

// Generic store configurator with improved typing; defaults preserve previous 'any' behavior
export function configureStore<S = any, A extends AnyAction = AnyAction>(
  initialState: PreloadedState<S>,
  rootReducer: Reducer<S, A>,
  sagaMiddleware: Array<any> = [],
  middleware: Array<any> = []
): Store<S, A> {
  const storeSagaMiddleware = createSagaMiddleware({
    onError: (error, errorInfo) => {
      // ApiAdapterException errors are handled by the AppApiAdapter
      if (!(error instanceof ApiAdapterException)) {
        AppLoggerUtils.logError(error);
      }
    },
  });

  let storeMiddleware: Array<any> = [];
  storeMiddleware.push(...middleware);
  storeMiddleware.push(storeSagaMiddleware);

  // Use conditional DevTools setup for better compatibility
  const composeEnhancers =
    (typeof window !== "undefined" &&
      (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
    compose;

  const appliedMiddleware = applyMiddleware(...storeMiddleware);
  const enhancer = composeEnhancers(appliedMiddleware);

  store = legacy_createStore<S, A, {}, {}>(
    rootReducer as Reducer<S, A>,
    initialState as PreloadedState<S>,
    enhancer
  );

  storeSagaMiddleware.run(defaultSaga);
  storeSagaMiddleware.run(rollResultSaga);
  for (let i = 0; i < sagaMiddleware.length; i++) {
    storeSagaMiddleware.run(sagaMiddleware[i]);
  }

  return store as Store<S, A>;
}
