import { createStore, Reducer, combineReducers, applyMiddleware, Action, StoreEnhancer } from "redux";
import { persistReducer, persistStore, PersistConfig, Persistor } from "redux-persist";
import storage from "redux-persist/lib/storage"; // defaults to localStorage for web
import { connectRouter, routerMiddleware } from "connected-react-router";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";

import { appReducer, appInitialState } from "./containers/App/reducer";
import { sitesReducer, sitesInitialState } from "./containers/Sites/reducer";
import { pageEditorReducer, pageEditorInitialState } from "./containers/PageEditor/reducer";
import { menuReducer, menuInitialState } from "./containers/Navigation/Menu/reducer";
import { navigationReducer, navigationInitialState } from "./containers/Navigation/Defaults/reducer";
import { structuredDataReducer, structuredDataInitialState } from "./containers/StructuredData/reducer";
import { languagesReducer, languagesInitialState } from "./containers/Settings/Languages/reducer";
import { dataPacksReducer, dataPacksInitialState } from "./containers/Settings/DataPacks/reducer";
import { socialReducer, socialInitialState } from "./containers/Settings/Social/reducer";
import { usersReducer, usersInitialState } from "./containers/Users/reducer";
import { galleryReducer, galleryInitialState } from "./containers/Gallery/reducer";
import { domainsReducer, domainsInitialState } from "./containers/Domains/reducer";
import { redirectsReducer, redirectsInitialState } from "./containers/Redirects/reducer";
import { analyticsReducer, analyticsInitialState } from "./containers/Analytics/reducer";
import { integrationsReducer, integrationsInitialState } from "./containers/Integrations/reducer";
import { fileDriveReducer, fileDriveInitialState } from "./containers/FileDrive/reducer";
import { formsReducer, formsInitialState } from "./containers/Forms/reducer";
import { activityLogReducer, activityLogInitialState } from "./containers/ActivityLog/reducer";
import { LOGOUT } from "./containers/App/constants";

import { IRootState } from "@ax/types";

const blacklist = ["router", "menu", "app", "languages"];
export class GlobalStore {
	private persistConfig: PersistConfig<any> = { key: "root", storage, blacklist };

	private authPersistConfig = {
		key: "app",
		storage,
		blacklist: ["error", "isLoggingIn", "isRehydrated", "isSaving", "user"],
	};

	public configureStore(history: History) {
		let middleware: StoreEnhancer = applyMiddleware(thunk, routerMiddleware(history));

		const globalReducer: Reducer<any> = combineReducers({
			router: connectRouter(history),
			app: persistReducer(this.authPersistConfig, appReducer as Reducer<any, Action<any>>),
			sites: sitesReducer as Reducer<any, Action<any>>,
			pageEditor: pageEditorReducer as Reducer<any, Action<any>>,
			menu: menuReducer as Reducer<any, Action<any>>,
			navigation: navigationReducer as Reducer<any, Action<any>>,
			structuredData: structuredDataReducer as Reducer<any, Action<any>>,
			languages: languagesReducer as Reducer<any, Action<any>>,
			dataPacks: dataPacksReducer as Reducer<any, Action<any>>,
			social: socialReducer as Reducer<any, Action<any>>,
			users: usersReducer as Reducer<any, Action<any>>,
			gallery: galleryReducer as Reducer<any, Action<any>>,
			domains: domainsReducer as Reducer<any, Action<any>>,
			redirects: redirectsReducer as Reducer<any, Action<any>>,
			analytics: analyticsReducer as Reducer<any, Action<any>>,
			integrations: integrationsReducer as Reducer<any, Action<any>>,
			fileDrive: fileDriveReducer as Reducer<any, Action<any>>,
			forms: formsReducer as Reducer<any, Action<any>>,
			activityLog: activityLogReducer as Reducer<any, Action<any>>,
		});

		const rootReducer = (state: IRootState | undefined, action: any) => {
			if (action.type === LOGOUT) {
				state = {
					router: state?.router,
					app: state?.app || appInitialState,
					sites: sitesInitialState,
					pageEditor: pageEditorInitialState,
					menu: menuInitialState,
					navigation: navigationInitialState,
					structuredData: structuredDataInitialState,
					languages: languagesInitialState,
					dataPacks: dataPacksInitialState,
					social: socialInitialState,
					users: usersInitialState,
					gallery: galleryInitialState,
					domains: domainsInitialState,
					redirects: redirectsInitialState,
					analytics: analyticsInitialState,
					integrations: integrationsInitialState,
					fileDrive: fileDriveInitialState,
					forms: formsInitialState,
					activityLog: activityLogInitialState,
				};
			}

			return globalReducer(state, action);
		};

		if (process.env.NODE_ENV !== "production") {
			middleware = composeWithDevTools(middleware);
		}
		const store = createStore(persistReducer(this.persistConfig, rootReducer), middleware);
		const persistor: Persistor = persistStore(store);
		return { store, persistor };
	}
}
