/**
 * This file is part of the NocoBase (R) project.
 * Copyright (c) 2020-2024 NocoBase Co., Ltd.
 * Authors: NocoBase Team.
 *
 * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
 * For more information, please refer to: https://www.nocobase.com/agreement.
 */

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 route_sync_exports = {};
__export(route_sync_exports, {
  FlowSurfaceRouteSync: () => FlowSurfaceRouteSync
});
module.exports = __toCommonJS(route_sync_exports);
var import_lodash = __toESM(require("lodash"));
var import_builder = require("./builder");
class FlowSurfaceRouteSync {
  constructor(db, repository, patchModel = (values, options) => repository.patch(values, options)) {
    this.db = db;
    this.repository = repository;
    this.patchModel = patchModel;
  }
  async buildPageTree(pageRouteLike, transaction) {
    var _a, _b, _c, _d, _e, _f, _g;
    const pageRoute = await this.hydrateRoute(pageRouteLike, transaction);
    const pageSchemaUid = ((_a = pageRoute == null ? void 0 : pageRoute.get) == null ? void 0 : _a.call(pageRoute, "schemaUid")) || (pageRoute == null ? void 0 : pageRoute.schemaUid);
    const pageModel = await this.repository.findModelByParentId(pageSchemaUid, {
      transaction,
      subKey: "page",
      includeAsyncNode: true
    });
    const tabs = await Promise.all(
      import_lodash.default.sortBy(
        import_lodash.default.castArray(((_b = pageRoute == null ? void 0 : pageRoute.get) == null ? void 0 : _b.call(pageRoute, "children")) || (pageRoute == null ? void 0 : pageRoute.children) || []),
        (item) => {
          var _a2;
          return ((_a2 = item == null ? void 0 : item.get) == null ? void 0 : _a2.call(item, "sort")) ?? (item == null ? void 0 : item.sort);
        }
      ).map((route) => this.buildTabAnchor(route, transaction))
    );
    const routeBacked = this.readPageRouteBackedState(pageRoute, pageModel);
    if (pageModel == null ? void 0 : pageModel.uid) {
      return {
        ...pageModel,
        props: {
          ...pageModel.props || {},
          routeId: ((_c = pageRoute == null ? void 0 : pageRoute.get) == null ? void 0 : _c.call(pageRoute, "id")) || (pageRoute == null ? void 0 : pageRoute.id),
          ...routeBacked
        },
        stepParams: {
          ...pageModel.stepParams || {},
          pageSettings: {
            ...((_d = pageModel.stepParams) == null ? void 0 : _d.pageSettings) || {},
            general: {
              ...((_f = (_e = pageModel.stepParams) == null ? void 0 : _e.pageSettings) == null ? void 0 : _f.general) || {},
              ...routeBacked
            }
          }
        },
        subModels: {
          ...pageModel.subModels || {},
          tabs
        }
      };
    }
    return {
      uid: pageSchemaUid,
      use: "RootPageModel",
      props: {
        routeId: ((_g = pageRoute == null ? void 0 : pageRoute.get) == null ? void 0 : _g.call(pageRoute, "id")) || (pageRoute == null ? void 0 : pageRoute.id),
        ...routeBacked
      },
      stepParams: {
        pageSettings: {
          general: {
            ...routeBacked
          }
        }
      },
      subModels: {
        tabs
      }
    };
  }
  async buildTabAnchor(tabRouteLike, transaction) {
    var _a, _b, _c;
    const tabRoute = await this.hydrateRoute(tabRouteLike, transaction);
    const schemaUid = ((_a = tabRoute == null ? void 0 : tabRoute.get) == null ? void 0 : _a.call(tabRoute, "schemaUid")) || (tabRoute == null ? void 0 : tabRoute.schemaUid);
    const routeNode = await this.repository.findModelById(schemaUid, {
      transaction,
      includeAsyncNode: true
    });
    const grid = ((_b = routeNode == null ? void 0 : routeNode.subModels) == null ? void 0 : _b.grid) || await this.repository.findModelByParentId(schemaUid, {
      transaction,
      subKey: "grid",
      includeAsyncNode: true
    });
    return (0, import_builder.buildSyntheticRootPageTabModel)({
      uid: schemaUid,
      use: (routeNode == null ? void 0 : routeNode.use) || "RootPageTabModel",
      props: (routeNode == null ? void 0 : routeNode.props) || {},
      decoratorProps: (routeNode == null ? void 0 : routeNode.decoratorProps) || {},
      flowRegistry: readRouteOptions(tabRoute).flowRegistry || (routeNode == null ? void 0 : routeNode.flowRegistry) || {},
      stepParams: (routeNode == null ? void 0 : routeNode.stepParams) || {},
      route: ((_c = tabRoute == null ? void 0 : tabRoute.toJSON) == null ? void 0 : _c.call(tabRoute)) || tabRoute,
      title: readRouteProp(tabRoute, "title"),
      icon: readRouteProp(tabRoute, "icon"),
      documentTitle: readRouteOptions(tabRoute).documentTitle,
      grid
    });
  }
  async removeRouteAnchorChildren(schemaUid, transaction) {
    if (!schemaUid) {
      return;
    }
    const node = await this.repository.findModelById(schemaUid, {
      transaction,
      includeAsyncNode: true
    });
    const children = Object.values((node == null ? void 0 : node.subModels) || {}).flatMap((value) => import_lodash.default.castArray(value));
    for (const child of children) {
      await this.repository.remove(child.uid, { transaction });
    }
    const asyncGridChild = await this.repository.findModelByParentId(schemaUid, {
      transaction,
      subKey: "grid",
      includeAsyncNode: true
    });
    if (asyncGridChild == null ? void 0 : asyncGridChild.uid) {
      await this.repository.remove(asyncGridChild.uid, { transaction });
    }
  }
  async removeTabAnchorTree(schemaUid, transaction) {
    const tabAnchor = await this.findPersistedTabAnchor(schemaUid, transaction);
    if (tabAnchor == null ? void 0 : tabAnchor.uid) {
      await this.repository.remove(tabAnchor.uid, { transaction });
      return;
    }
    await this.removeRouteAnchorChildren(schemaUid, transaction);
  }
  async persistPageSettings(target, current, nextPayload, transaction) {
    var _a, _b;
    const route = await this.hydrateRoute(target.pageRoute, transaction);
    const routeValues = this.buildPageRoutePatch(current, nextPayload, route);
    if (Object.keys(routeValues).length) {
      await this.db.getRepository("desktopRoutes").update({
        filterByTk: String(route.get("id")),
        values: routeValues,
        transaction
      });
      if (Object.prototype.hasOwnProperty.call(routeValues, "enableTabs")) {
        const tabRouteHidden = !routeValues.enableTabs;
        await Promise.all(
          import_lodash.default.castArray(((_a = route == null ? void 0 : route.get) == null ? void 0 : _a.call(route, "children")) || (route == null ? void 0 : route.children) || []).map((tabRoute) => {
            var _a2;
            return ((_a2 = tabRoute == null ? void 0 : tabRoute.get) == null ? void 0 : _a2.call(tabRoute, "id")) ?? (tabRoute == null ? void 0 : tabRoute.id);
          }).filter((routeId) => !import_lodash.default.isNil(routeId) && routeId !== "").map(
            (routeId) => this.db.getRepository("desktopRoutes").update({
              filterByTk: String(routeId),
              values: {
                hidden: tabRouteHidden
              },
              transaction
            })
          )
        );
      }
    }
    const pageSchemaUid = ((_b = route == null ? void 0 : route.get) == null ? void 0 : _b.call(route, "schemaUid")) || (route == null ? void 0 : route.schemaUid);
    const pageModel = target.pageModel || (pageSchemaUid ? await this.repository.findModelByParentId(pageSchemaUid, {
      transaction,
      subKey: "page",
      includeAsyncNode: true
    }) : null);
    if (pageModel == null ? void 0 : pageModel.uid) {
      await this.patchModel(
        {
          ...this.normalizePagePayload(current, nextPayload, routeValues),
          uid: pageModel.uid
        },
        { transaction }
      );
    }
  }
  async persistTabSettings(target, current, nextPayload, transaction) {
    const route = await this.hydrateRoute(target.tabRoute, transaction);
    const routeValues = this.buildTabRoutePatch(current, nextPayload, route);
    if (Object.keys(routeValues).length) {
      await this.db.getRepository("desktopRoutes").update({
        filterByTk: String(route.get("id")),
        values: routeValues,
        transaction
      });
    }
    const tabAnchor = await this.findPersistedTabAnchor(target.uid || (current == null ? void 0 : current.uid), transaction);
    if (!(tabAnchor == null ? void 0 : tabAnchor.uid)) {
      return;
    }
    const latestRoute = await this.hydrateRoute(target.tabRoute, transaction);
    await this.patchModel(
      this.normalizeTabPayload(await this.buildTabAnchor(latestRoute, transaction), nextPayload, routeValues),
      { transaction }
    );
  }
  async findPersistedTabAnchor(schemaUid, transaction) {
    const node = await this.repository.findModelById(schemaUid, {
      transaction,
      includeAsyncNode: true
    });
    if ((node == null ? void 0 : node.use) === "RootPageTabModel" || (node == null ? void 0 : node.use) === "ChildPageTabModel") {
      return node;
    }
    return null;
  }
  async hydrateRoute(routeLike, transaction) {
    var _a;
    if (!((_a = routeLike == null ? void 0 : routeLike.get) == null ? void 0 : _a.call(routeLike, "id"))) {
      return routeLike;
    }
    return this.db.getRepository("desktopRoutes").findOne({
      filterByTk: String(routeLike.get("id")),
      appends: ["children"],
      transaction
    });
  }
  readPageRouteBackedState(route, pageModel) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
    return {
      title: readRouteProp(route, "title") ?? ((_a = pageModel == null ? void 0 : pageModel.props) == null ? void 0 : _a.title) ?? ((_d = (_c = (_b = pageModel == null ? void 0 : pageModel.stepParams) == null ? void 0 : _b.pageSettings) == null ? void 0 : _c.general) == null ? void 0 : _d.title),
      icon: readRouteProp(route, "icon") ?? ((_e = pageModel == null ? void 0 : pageModel.props) == null ? void 0 : _e.icon) ?? ((_h = (_g = (_f = pageModel == null ? void 0 : pageModel.stepParams) == null ? void 0 : _f.pageSettings) == null ? void 0 : _g.general) == null ? void 0 : _h.icon),
      enableTabs: !!(readRouteProp(route, "enableTabs") ?? ((_i = pageModel == null ? void 0 : pageModel.props) == null ? void 0 : _i.enableTabs) ?? ((_l = (_k = (_j = pageModel == null ? void 0 : pageModel.stepParams) == null ? void 0 : _j.pageSettings) == null ? void 0 : _k.general) == null ? void 0 : _l.enableTabs)),
      enableHeader: firstDefined(
        readRouteProp(route, "enableHeader"),
        (_m = pageModel == null ? void 0 : pageModel.props) == null ? void 0 : _m.enableHeader,
        (_p = (_o = (_n = pageModel == null ? void 0 : pageModel.stepParams) == null ? void 0 : _n.pageSettings) == null ? void 0 : _o.general) == null ? void 0 : _p.enableHeader
      ),
      displayTitle: !!(readRouteProp(route, "displayTitle") ?? ((_q = pageModel == null ? void 0 : pageModel.props) == null ? void 0 : _q.displayTitle) ?? ((_t = (_s = (_r = pageModel == null ? void 0 : pageModel.stepParams) == null ? void 0 : _r.pageSettings) == null ? void 0 : _s.general) == null ? void 0 : _t.displayTitle) ?? true)
    };
  }
  buildPageRoutePatch(current, nextPayload, route) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const nextProps = nextPayload.props || {};
    const nextGeneral = ((_b = (_a = nextPayload.stepParams) == null ? void 0 : _a.pageSettings) == null ? void 0 : _b.general) || {};
    const routePatch = {};
    const nextTitle = firstDefined(nextGeneral.title, nextProps.title);
    const nextIcon = firstDefined(nextGeneral.icon, nextProps.icon);
    const nextEnableTabs = firstDefined(nextGeneral.enableTabs, nextProps.enableTabs);
    const nextEnableHeader = firstDefined(nextGeneral.enableHeader, nextProps.enableHeader);
    const nextDisplayTitle = firstDefined(nextGeneral.displayTitle, nextProps.displayTitle);
    if (!import_lodash.default.isUndefined(nextTitle)) {
      routePatch.title = nextTitle;
    }
    if (!import_lodash.default.isUndefined(nextIcon)) {
      routePatch.icon = nextIcon;
    }
    if (!import_lodash.default.isUndefined(nextEnableTabs)) {
      routePatch.enableTabs = !!nextEnableTabs;
    }
    if (!import_lodash.default.isUndefined(nextEnableHeader)) {
      routePatch.enableHeader = !!nextEnableHeader;
    }
    if (!import_lodash.default.isUndefined(nextDisplayTitle)) {
      routePatch.displayTitle = !!nextDisplayTitle;
    }
    if (!Object.keys(routePatch).length) {
      return {};
    }
    return {
      title: routePatch.title ?? readRouteProp(route, "title") ?? ((_c = current == null ? void 0 : current.props) == null ? void 0 : _c.title),
      ...!import_lodash.default.isUndefined(routePatch.icon) ? { icon: routePatch.icon } : {},
      enableTabs: routePatch.enableTabs ?? !!(readRouteProp(route, "enableTabs") ?? ((_d = current == null ? void 0 : current.props) == null ? void 0 : _d.enableTabs)),
      ...!import_lodash.default.isUndefined(routePatch.enableHeader) ? { enableHeader: routePatch.enableHeader } : !import_lodash.default.isUndefined(readRouteProp(route, "enableHeader")) ? { enableHeader: !!readRouteProp(route, "enableHeader") } : {},
      displayTitle: routePatch.displayTitle ?? !!(readRouteProp(route, "displayTitle") ?? ((_e = current == null ? void 0 : current.props) == null ? void 0 : _e.displayTitle) ?? ((_h = (_g = (_f = current == null ? void 0 : current.stepParams) == null ? void 0 : _f.pageSettings) == null ? void 0 : _g.general) == null ? void 0 : _h.displayTitle) ?? true)
    };
  }
  normalizePagePayload(current, nextPayload, routePatch) {
    var _a, _b;
    if (!Object.keys(routePatch).length) {
      return nextPayload;
    }
    const pageSettings = ((_a = current == null ? void 0 : current.stepParams) == null ? void 0 : _a.pageSettings) || {};
    const nextPageSettings = ((_b = nextPayload.stepParams) == null ? void 0 : _b.pageSettings) || {};
    return {
      ...nextPayload,
      props: {
        ...(current == null ? void 0 : current.props) || {},
        ...nextPayload.props || {},
        ...routePatch
      },
      stepParams: {
        ...(current == null ? void 0 : current.stepParams) || {},
        ...nextPayload.stepParams || {},
        pageSettings: {
          ...pageSettings,
          ...nextPageSettings,
          general: {
            ...pageSettings.general || {},
            ...nextPageSettings.general || {},
            ...routePatch
          }
        }
      }
    };
  }
  buildTabRoutePatch(_current, nextPayload, route) {
    var _a, _b;
    const nextProps = nextPayload.props || {};
    const nextTab = ((_b = (_a = nextPayload.stepParams) == null ? void 0 : _a.pageTabSettings) == null ? void 0 : _b.tab) || {};
    const routeOptions = readRouteOptions(route);
    const patch = {};
    const nextTitle = firstDefined(nextTab.title, nextProps.title);
    const nextIcon = firstDefined(nextTab.icon, nextProps.icon);
    if (!import_lodash.default.isUndefined(nextTitle)) {
      patch.title = nextTitle;
    }
    if (!import_lodash.default.isUndefined(nextIcon)) {
      patch.icon = nextIcon;
    }
    const nextOptions = {
      ...routeOptions || {},
      ...!import_lodash.default.isUndefined(nextTab.documentTitle) ? { documentTitle: nextTab.documentTitle } : {},
      ...!import_lodash.default.isUndefined(nextPayload.flowRegistry) ? { flowRegistry: nextPayload.flowRegistry } : {}
    };
    if (!import_lodash.default.isEqual(nextOptions, routeOptions || {})) {
      patch.options = nextOptions;
    }
    if (!Object.keys(patch).length) {
      return {};
    }
    return {
      ...!import_lodash.default.isUndefined(patch.title) ? { title: patch.title } : {},
      ...!import_lodash.default.isUndefined(patch.icon) ? { icon: patch.icon } : {},
      ...patch.options ? { options: patch.options } : {}
    };
  }
  normalizeTabPayload(current, nextPayload, routePatch) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const currentTab = ((_b = (_a = current == null ? void 0 : current.stepParams) == null ? void 0 : _a.pageTabSettings) == null ? void 0 : _b.tab) || {};
    const nextTab = ((_d = (_c = nextPayload.stepParams) == null ? void 0 : _c.pageTabSettings) == null ? void 0 : _d.tab) || {};
    const routeBackedTab = {
      ...!import_lodash.default.isUndefined(routePatch.title) ? { title: routePatch.title } : {},
      ...!import_lodash.default.isUndefined(routePatch.icon) ? { icon: routePatch.icon } : {},
      ...!import_lodash.default.isUndefined((_e = routePatch.options) == null ? void 0 : _e.documentTitle) ? { documentTitle: routePatch.options.documentTitle } : {}
    };
    return {
      ...nextPayload,
      props: {
        ...(current == null ? void 0 : current.props) || {},
        ...nextPayload.props || {},
        ...import_lodash.default.pick(routeBackedTab, ["title", "icon"])
      },
      stepParams: {
        ...(current == null ? void 0 : current.stepParams) || {},
        ...nextPayload.stepParams || {},
        pageTabSettings: {
          ...((_f = current == null ? void 0 : current.stepParams) == null ? void 0 : _f.pageTabSettings) || {},
          ...((_g = nextPayload.stepParams) == null ? void 0 : _g.pageTabSettings) || {},
          tab: {
            ...currentTab,
            ...nextTab,
            ...routeBackedTab
          }
        }
      },
      flowRegistry: !import_lodash.default.isUndefined((_h = routePatch.options) == null ? void 0 : _h.flowRegistry) ? routePatch.options.flowRegistry : !import_lodash.default.isUndefined(nextPayload.flowRegistry) ? nextPayload.flowRegistry : current == null ? void 0 : current.flowRegistry
    };
  }
}
function readRouteProp(route, key) {
  var _a;
  return ((_a = route == null ? void 0 : route.get) == null ? void 0 : _a.call(route, key)) ?? (route == null ? void 0 : route[key]);
}
function readRouteOptions(route) {
  var _a;
  return ((_a = route == null ? void 0 : route.get) == null ? void 0 : _a.call(route, "options")) || (route == null ? void 0 : route.options) || {};
}
function firstDefined(...values) {
  return values.find((value) => !import_lodash.default.isUndefined(value));
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  FlowSurfaceRouteSync
});
