/**
 * pages reducer
 */
import * as reducer from "./reducers"
import reducerFromMap from "@racletteCore/lib/reducerFromMap"
import { applicationState } from "@racletteCore/store/state"
import { tap, distinctUntilChanged, ignoreElements } from "rxjs/operators"
import { actions$, ofType } from "mini-rx-store"
import type { Composition } from "@shared/types/core/Composition.types"
import type { WidgetBase } from "../../types"
import { v4 as uuidv4 } from "uuid"
import { $store } from "@racletteCore"
import log from "@racletteCore/lib/logger"
import * as compositionsSelectors from "./selectors"
const reducerMap = {
  init: () => applicationState.pages,
  projectInit: reducer.projectInit,
  "compositions/add": reducer.compositionsAdd,
  "compositions/set": reducer.compositionsSet,
  "compositions/update": reducer.compositionsUpdate,
}

const makeWidget = (
  widget: Partial<WidgetBase>,
  widgets: WidgetBase[] = [],
) => {
  if (!widget) {
    return widgets
  }

  if (!widget.uuid) {
    widget.uuid = uuidv4()
  }
  const widgetsInState = $store.getState("widgets")
  if (!widgetsInState[widget.uuid]) {
    // make a generic widget state map
    widgets.push({
      uuid: widget.uuid,
      name: widget.name,
      pluginKey: widget.pluginKey,
      author: widget.author,
      version: widget.version,
      config: widget.config || {},
      public: widget.public || {},
    })
  } else {
    log.store("pages/add effect, widget already defined", widget)
  }

  return widgets
}

const compositionsEffects = (store) => {
  const add = actions$.pipe(
    ofType("compositions/set", "compositions/add"),
    distinctUntilChanged((prev, curr) => !store.hasChanges(prev, curr)),

    tap((action) => {
      const compositions: Composition[] = action.payload

      compositions.forEach((composition) => {
        let widgets: WidgetBase[] = []

        composition.widgetsLayout.forEach((column) =>
          column.forEach((slot) => {
            widgets = makeWidget(slot.widget, widgets)
          }),
        )
        // add page specific widget configs to state
        if (widgets.length > 0) {
          store.dispatch({
            type: "widgets/add",
            payload: widgets,
          })
        }
      })
    }),
    ignoreElements(),
  )

  return [add]
}
const compositionsReducers = reducerFromMap(reducerMap)

export { compositionsEffects, compositionsReducers, compositionsSelectors }
