import { mergeDeepRight, clone } from "ramda"
import { applicationState, storePatterns } from "@racletteCore/store/state"

const cleanWidgetState = (widget) => {
  const cleanWidget = clone(widget)
  delete cleanWidget.type
  // TODO implement empty state attribute deletion here, using removeEmpty
  return cleanWidget
}

/**
 * project init
 */
const projectInit = (state, action) => applicationState.widgets

/**
 * set widget config
 */
const widgetsSetConfig = (state, action) => {
  const newState = clone(state)

  if (!action.uuid) {
    return state
  }
  const widgetItem = mergeDeepRight(newState[action.uuid] || {}, action.payload)

  widgetItem.config = mergeDeepRight(
    action.payload?.config || {},
    widgetItem.config || {},
  )
  newState[action.uuid] = cleanWidgetState(widgetItem)

  return newState
}

/**
 * update widget
 */
const widgetsUpdate = (state, action) => {
  const newState = clone(state)

  if (!action.uuid) {
    return state
  }
  const { payload, override } = action

  // merge given payload onto widget state
  if (override) {
    for (const [key, value] of Object.entries(payload)) {
      newState[action.uuid][key] = value
    }
  } else {
    newState[action.uuid] = mergeDeepRight(state[action.uuid], action.payload)
  }
  newState[action.uuid] = cleanWidgetState(newState[action.uuid])

  return newState
}

/**
 * add widget
 */
const widgetsAdd = (state, action) => {
  const newWidgets = {}

  if (action.payload.length === 0) {
    return state
  }
  action.payload.forEach((widget) => {
    if (widget.uuid && state[widget.uuid]) {
      // if we are in widgets/add but the widget uuid already exists, we do
      // nothing as updates shall be done in widgets/update
      return state
    }
    // add page specific config to widget instance state
    if (!newWidgets[widget.uuid]) {
      newWidgets[widget.uuid] = cleanWidgetState(
        mergeDeepRight(storePatterns.widget, widget),
      )
    }
  })
  return mergeDeepRight(state, newWidgets)
}

export {
  widgetsUpdate,
  widgetsAdd,
  widgetsSetConfig,
  cleanWidgetState,
  projectInit,
}
