import { Type } from '@angular/core';
import { Action, combineReducers, Selector, createSelector } from '@ngrx/store';

import * as ChatStore from './chat';
import * as EventStore from './event';
import * as OptionStore from './option';
import * as QueryStore from './query';
import * as RoomStore from './room';
import * as StatusStore from './status';
import * as SyncStore from './sync';
import * as SettingsStore from './settings';

export interface State {
  chat: ChatStore.State;
  event: EventStore.State;
  option: OptionStore.State;
  query: QueryStore.State;
  room: RoomStore.State;
  status: StatusStore.State;
  sync: SyncStore.State;
  settings: SettingsStore.State;
}

export const effects: Type<any>[] = [
  ChatStore.Effects,
  EventStore.Effects,
  OptionStore.Effects,
  QueryStore.Effects,
  RoomStore.Effects,
  StatusStore.Effects,
  SyncStore.Effects,
  SettingsStore.Effects
];

export function reducers(state: State | undefined, action: Action) {
  return combineReducers({
    chat: ChatStore.reducer,
    event: EventStore.reducer,
    option: OptionStore.reducer,
    query: QueryStore.reducer,
    room: RoomStore.reducer,
    status: StatusStore.reducer,
    sync: SyncStore.reducer,
    settings: SettingsStore.reducer
  })(state, action);
}

export function selectors<S>(selector: Selector<any, State>) {
  return {
    ChatSelector: ChatStore.selectors(
      createSelector(selector, (state: State) => state.chat)
    ),
    EventSelector: EventStore.selectors(
      createSelector(selector, (state: State) => state.event)
    ),
    OptionSelector: OptionStore.selectors(
      createSelector(selector, (state: State) => state.option)
    ),
    RoomSelector: RoomStore.selectors(
      createSelector(selector, (state: State) => state.room)
    ),
    QuerySelector: QueryStore.selectors(
      createSelector(selector, (state: State) => state.query)
    ),
    StatusSelector: StatusStore.selectors(
      createSelector(selector, (state: State) => state.status)
    ),
    SyncSelector: SyncStore.selectors(
      createSelector(selector, (state: State) => state.sync)
    ),
    SettingsSelector: SettingsStore.selectors(
      createSelector(selector, (state: State) => state.settings)
    )
  };
}
