import { shallow } from 'zustand/shallow';
import { createWithEqualityFn } from 'zustand/traditional';
import { type StateCreator } from 'zustand/vanilla';

import { createDevtools } from '../middleware/createDevtools';
import { expose } from '../middleware/expose';
import { flattenActions } from '../utils/flattenActions';
import { type ElectronAppAction } from './actions/app';
import { createElectronAppSlice } from './actions/app';
import { type ElectronGatewayAction } from './actions/gateway';
import { gatewaySlice } from './actions/gateway';
import { type NavigationHistoryAction } from './actions/navigationHistory';
import { createNavigationHistorySlice } from './actions/navigationHistory';
import { type RecentPagesAction } from './actions/recentPages';
import { createRecentPagesSlice } from './actions/recentPages';
import { type ElectronSettingsAction } from './actions/settings';
import { settingsSlice } from './actions/settings';
import { type ElectronRemoteServerAction } from './actions/sync';
import { remoteSyncSlice } from './actions/sync';
import { type TabPagesAction } from './actions/tabPages';
import { createTabPagesSlice } from './actions/tabPages';
import { type ElectronState } from './initialState';
import { initialState } from './initialState';

//  ===============  Aggregate createStoreFn ============ //

export interface ElectronStore
  extends
    ElectronState,
    ElectronRemoteServerAction,
    ElectronAppAction,
    ElectronGatewayAction,
    ElectronSettingsAction,
    NavigationHistoryAction,
    RecentPagesAction,
    TabPagesAction {
  /* empty */
}

type ElectronStoreAction = ElectronRemoteServerAction &
  ElectronAppAction &
  ElectronGatewayAction &
  ElectronSettingsAction &
  NavigationHistoryAction &
  RecentPagesAction &
  TabPagesAction;

const createStore: StateCreator<ElectronStore, [['zustand/devtools', never]]> = (
  ...parameters: Parameters<StateCreator<ElectronStore, [['zustand/devtools', never]]>>
) => ({
  ...initialState,
  ...flattenActions<ElectronStoreAction>([
    remoteSyncSlice(...parameters),
    createElectronAppSlice(...parameters),
    gatewaySlice(...parameters),
    settingsSlice(...parameters),
    createNavigationHistorySlice(...parameters),
    createRecentPagesSlice(...parameters),
    createTabPagesSlice(...parameters),
  ]),
});

//  ===============  Implement useStore ============ //

const devtools = createDevtools('electron');

export const useElectronStore = createWithEqualityFn<ElectronStore>()(
  devtools(createStore),
  shallow,
);

expose('electron', useElectronStore);

export const getElectronStoreState = () => useElectronStore.getState();
