"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var react_page_exports = {};
__export(react_page_exports, {
  configureStore: () => configureStore,
  copyElementTree: () => copyElementTree,
  createBaseDocument: () => import_read_only_documents.createBaseDocument,
  createDocumentReference: () => import_read_only_documents.createDocumentReference,
  elementTreeMiddleware: () => elementTreeMiddleware,
  getBreakpoints: () => getBreakpoints,
  getBuilderEditMode: () => getBuilderEditMode,
  getComponentMeta: () => getComponentMeta,
  getComponentPropControllerDescriptors: () => getComponentPropControllerDescriptors,
  getDocument: () => getDocument,
  getDocumentKeysSortedByDepth: () => getDocumentKeysSortedByDepth,
  getElement: () => getElement,
  getElementId: () => getElementId,
  getElementIds: () => getElementIds,
  getElementPropControllerDescriptors: () => getElementPropControllerDescriptors,
  getElements: () => getElements,
  getIsInBuilder: () => getIsInBuilder,
  getIsPreview: () => getIsPreview,
  getPropControllerDescriptors: () => getPropControllerDescriptors,
  getPropControllers: () => getPropControllers,
  getReactComponent: () => getReactComponent,
  getRootElement: () => import_read_only_documents.getRootElement,
  isElementReference: () => import_read_only_documents.isElementReference,
  mergeElement: () => mergeElement
});
module.exports = __toCommonJS(react_page_exports);
var import_toolkit = require("@reduxjs/toolkit");
var import_reselect = require("reselect");
var import_controls = require("@makeswift/controls");
var import_control = require("../controls/control");
var Documents = __toESM(require("./modules/read-only-documents"));
var ElementTrees = __toESM(require("./modules/element-trees"));
var ReactComponents = __toESM(require("./modules/react-components"));
var ComponentsMeta = __toESM(require("./modules/components-meta"));
var PropControllers = __toESM(require("./modules/prop-controllers"));
var PropControllerHandles = __toESM(require("./modules/prop-controller-handles"));
var IsInBuilder = __toESM(require("./modules/is-in-builder"));
var IsPreview = __toESM(require("./modules/is-preview"));
var BuilderEditMode = __toESM(require("./modules/builder-edit-mode"));
var Breakpoints = __toESM(require("./modules/breakpoints"));
var import_actions = require("./actions");
var import_internal = require("./actions/internal");
var import_toolkit2 = require("./toolkit");
var import_setup_teardown = require("./mixins/setup-teardown");
var import_read_only_documents = require("./modules/read-only-documents");
const reducer = (0, import_toolkit.combineReducers)({
  documents: Documents.reducer,
  elementTrees: ElementTrees.reducer,
  reactComponents: ReactComponents.reducer,
  componentsMeta: ComponentsMeta.reducer,
  propControllers: PropControllers.reducer,
  propControllerHandles: PropControllerHandles.reducer,
  isInBuilder: IsInBuilder.reducer,
  isPreview: IsPreview.reducer,
  builderEditMode: BuilderEditMode.reducer,
  breakpoints: Breakpoints.reducer
});
function getDocumentsStateSlice(state) {
  return state.documents;
}
function getDocument(state, documentKey) {
  return Documents.getDocument(getDocumentsStateSlice(state), documentKey);
}
function getElementTreesSlice(state) {
  return state.elementTrees;
}
function getElements(state, documentKey) {
  return ElementTrees.getElements(getElementTreesSlice(state), documentKey);
}
function getElementIds(state, documentKey) {
  return ElementTrees.getElementIds(getElementTreesSlice(state), documentKey);
}
function getReactComponentsStateSlice(state) {
  return state.reactComponents;
}
function getReactComponent(state, type) {
  return ReactComponents.getReactComponent(getReactComponentsStateSlice(state), type);
}
function getComponentsMetaStateSlice(state) {
  return state.componentsMeta;
}
function getComponentMeta(state, type) {
  return ComponentsMeta.getComponentMeta(getComponentsMetaStateSlice(state), type);
}
function getPropControllersStateSlice(state) {
  return state.propControllers;
}
function getPropControllerDescriptors(state) {
  return PropControllers.getPropControllerDescriptors(getPropControllersStateSlice(state));
}
function getComponentPropControllerDescriptors(state, componentType) {
  return PropControllers.getComponentPropControllerDescriptors(
    getPropControllersStateSlice(state),
    componentType
  );
}
function getPropControllerHandlesStateSlice(state) {
  return state.propControllerHandles;
}
function getPropControllers(state, documentKey, elementKey) {
  return PropControllerHandles.getPropControllers(
    getPropControllerHandlesStateSlice(state),
    documentKey,
    elementKey
  );
}
const getDocumentKeysSortedByDepth = (0, import_reselect.createSelector)(
  [getDocumentsStateSlice, getElementTreesSlice],
  (documents, elementTrees) => {
    return [...documents.keys()].sort((a, b) => elementTrees.get(a)?.elements.has(b) ? -1 : 1);
  }
);
function getElement(state, documentKey, elementKey) {
  return ElementTrees.getElement(getElementTreesSlice(state), documentKey, elementKey);
}
function getElementId(state, documentKey, elementKey) {
  return ElementTrees.getElementId(getElementTreesSlice(state), documentKey, elementKey);
}
function getElementPropControllerDescriptors(state, documentKey, elementKey) {
  const element = getElement(state, documentKey, elementKey);
  if (element == null || Documents.isElementReference(element))
    return null;
  return getComponentPropControllerDescriptors(state, element.type);
}
function copyElementTree(state, elementTree, replacementContext) {
  function copyElementTreeNode(state2, replacementContext2) {
    return function(node) {
      const context = {
        replacementContext: replacementContext2,
        copyElement: copyElementTreeNode(state2, replacementContext2)
      };
      if (Documents.isElementReference(node)) {
        return {
          ...node,
          value: (0, import_controls.replaceResourceIfNeeded)(import_controls.ContextResource.GlobalElement, node.value, context)
        };
      }
      const descriptors = getComponentPropControllerDescriptors(state2, node.type);
      if (descriptors == null)
        return node;
      for (const [propKey, descriptor] of Object.entries(descriptors)) {
        node.props[propKey] = (0, import_control.copy)(descriptor, node.props[propKey], context);
      }
      return node;
    };
  }
  const copy = JSON.parse(JSON.stringify(elementTree));
  return copyElementTreeNode(state, (0, import_controls.createReplacementContext)(replacementContext))(copy);
}
function mergeElement(state, baseElement, overrideElement) {
  if (baseElement.type !== overrideElement.type || baseElement.key !== overrideElement.key) {
    throw new Error(`Can't merge elements of different types or keys`);
  }
  if (Documents.isElementReference(overrideElement))
    return overrideElement;
  if (Documents.isElementReference(baseElement))
    return baseElement;
  const elementDescriptors = getPropControllerDescriptors(state);
  const descriptors = elementDescriptors.get(baseElement.type);
  if (descriptors == null) {
    throw new Error(
      `Can't merge element of type "${baseElement.type}" because it has no descriptors`
    );
  }
  const mergedProps = {};
  for (const propName of Object.keys(descriptors)) {
    const descriptor = descriptors[propName];
    const context = {
      mergeElement(base, override) {
        return mergeElement(state, base, override);
      }
    };
    mergedProps[propName] = (0, import_control.merge)(
      descriptor,
      baseElement.props[propName],
      overrideElement.props[propName],
      context
    );
  }
  return { ...baseElement, props: mergedProps };
}
function getIsInBuilder(state) {
  return state.isInBuilder;
}
function getIsPreview(state) {
  return IsPreview.getIsPreview(state.isPreview);
}
function getBuilderEditMode(state) {
  return state.builderEditMode;
}
function getBreakpoints(state) {
  return state.breakpoints;
}
function elementTreeMiddleware() {
  return (0, import_toolkit2.actionMiddleware)(({ dispatch, getState }) => (next) => {
    return (action) => {
      switch (action.type) {
        case import_actions.ActionTypes.REGISTER_DOCUMENT:
          dispatch(
            (0, import_internal.createElementTree)({
              document: action.payload.document,
              descriptors: getPropControllerDescriptors(getState())
            })
          );
          break;
        case import_actions.ActionTypes.CHANGE_DOCUMENT: {
          const { documentKey, operation } = action.payload;
          const oldDocument = getDocument(getState(), documentKey);
          const result = next(action);
          const newDocument = getDocument(getState(), documentKey);
          if (oldDocument != null && newDocument != null && newDocument !== oldDocument) {
            dispatch(
              (0, import_internal.changeElementTree)({
                oldDocument,
                newDocument,
                descriptors: getPropControllerDescriptors(getState()),
                operation
              })
            );
          }
          return result;
        }
        case import_actions.ActionTypes.UNREGISTER_DOCUMENT:
          dispatch((0, import_internal.deleteElementTree)(action.payload));
          break;
      }
      return next(action);
    };
  });
}
function configureStore({
  name,
  preloadedState,
  breakpoints
}) {
  return (0, import_toolkit.configureStore)({
    reducer,
    preloadedState: {
      ...preloadedState,
      breakpoints: Breakpoints.getInitialState(breakpoints ?? preloadedState?.breakpoints)
    },
    middleware: (getDefaultMiddleware) => getDefaultMiddleware(import_toolkit2.middlewareOptions).concat(elementTreeMiddleware()),
    enhancers: (getDefaultEnhancers) => getDefaultEnhancers().concat(
      (0, import_setup_teardown.withSetupTeardown)(
        () => {
        },
        () => {
        }
      )
    ),
    devTools: (0, import_toolkit2.devToolsConfig)({
      name: `${name} (${(/* @__PURE__ */ new Date()).toISOString()})`
    })
  });
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  configureStore,
  copyElementTree,
  createBaseDocument,
  createDocumentReference,
  elementTreeMiddleware,
  getBreakpoints,
  getBuilderEditMode,
  getComponentMeta,
  getComponentPropControllerDescriptors,
  getDocument,
  getDocumentKeysSortedByDepth,
  getElement,
  getElementId,
  getElementIds,
  getElementPropControllerDescriptors,
  getElements,
  getIsInBuilder,
  getIsPreview,
  getPropControllerDescriptors,
  getPropControllers,
  getReactComponent,
  getRootElement,
  isElementReference,
  mergeElement
});
//# sourceMappingURL=react-page.js.map