/**
 * 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 surface_context_exports = {};
__export(surface_context_exports, {
  FlowSurfaceContextResolver: () => FlowSurfaceContextResolver
});
module.exports = __toCommonJS(surface_context_exports);
var import_lodash = __toESM(require("lodash"));
var import_action_scope = require("./action-scope");
var import_catalog = require("./catalog");
var import_chart_config = require("./chart-config");
var import_errors = require("./errors");
var import_approval = require("./approval");
var import_placement = require("./placement");
const FILTER_TARGET_BLOCK_USES = /* @__PURE__ */ new Set([
  "TableBlockModel",
  "CalendarBlockModel",
  "KanbanBlockModel",
  "DetailsBlockModel",
  "ListBlockModel",
  "GridCardBlockModel",
  "ChartBlockModel",
  "MapBlockModel",
  "CommentsBlockModel",
  "RecordHistoryBlockModel"
]);
const DETAILS_CARD_BLOCK_USES = /* @__PURE__ */ new Set(["ListBlockModel", "GridCardBlockModel", "KanbanBlockModel"]);
const DETAILS_CARD_ITEM_USES = /* @__PURE__ */ new Set(["ListItemModel", "GridCardItemModel", "KanbanCardItemModel"]);
function getDefaultGridUse(ownerUse, fallbackUse) {
  return (0, import_approval.getApprovalDefaultGridUse)(ownerUse) || fallbackUse;
}
function getFieldWrapperUse(containerUse, fallbackUse) {
  return (0, import_approval.getApprovalFieldWrapperUse)(containerUse) || fallbackUse;
}
class FlowSurfaceContextResolver {
  constructor(repository, locator, options) {
    this.repository = repository;
    this.locator = locator;
    this.options = options;
  }
  resolveBlockCatalogContainerUse(targetNode, resolved) {
    var _a, _b, _c, _d, _e, _f, _g;
    if (!targetNode && !resolved) {
      return void 0;
    }
    if ((_b = (_a = targetNode == null ? void 0 : targetNode.use) == null ? void 0 : _a.endsWith) == null ? void 0 : _b.call(_a, "GridModel")) {
      return targetNode.use;
    }
    if ((_d = (_c = targetNode == null ? void 0 : targetNode.subModels) == null ? void 0 : _c.grid) == null ? void 0 : _d.use) {
      return targetNode.subModels.grid.use;
    }
    const firstTab = import_lodash.default.castArray(((_e = targetNode == null ? void 0 : targetNode.subModels) == null ? void 0 : _e.tabs) || [])[0];
    if ((_g = (_f = firstTab == null ? void 0 : firstTab.subModels) == null ? void 0 : _f.grid) == null ? void 0 : _g.use) {
      return firstTab.subModels.grid.use;
    }
    const directDefaultGridUse = (0, import_approval.getApprovalDefaultGridUse)(targetNode == null ? void 0 : targetNode.use);
    if (directDefaultGridUse) {
      return directDefaultGridUse;
    }
    const firstTabDefaultGridUse = (0, import_approval.getApprovalDefaultGridUse)(firstTab == null ? void 0 : firstTab.use);
    if (firstTabDefaultGridUse) {
      return firstTabDefaultGridUse;
    }
    return void 0;
  }
  filterBlocksByTarget(targetNode, resolved) {
    const containerUse = this.resolveBlockCatalogContainerUse(targetNode, resolved);
    const blocks = (0, import_catalog.getAvailableBlockCatalogItems)(containerUse);
    if (!targetNode && !resolved) {
      return blocks;
    }
    if ((0, import_placement.canCatalogAddBlock)({ node: targetNode, resolved })) {
      return blocks;
    }
    return [];
  }
  async resolveFilterFormTarget(filterFormOwnerUid, targetBlockUid, transaction) {
    const targets = await this.collectFilterFormTargets(filterFormOwnerUid, transaction);
    if (!targets.length) {
      (0, import_errors.throwBadRequest)("flowSurfaces addField cannot find filter targets on the current surface");
    }
    if (targetBlockUid) {
      const matched = targets.find((item) => item.ownerUid === targetBlockUid);
      if (!matched) {
        (0, import_errors.throwBadRequest)(
          `flowSurfaces addField filter target '${targetBlockUid}' is not available on the current surface`
        );
      }
      return matched;
    }
    if (targets.length > 1) {
      (0, import_errors.throwBadRequest)(
        "flowSurfaces addField on filter-form requires defaultTargetUid when multiple target blocks are available"
      );
    }
    return targets[0];
  }
  async collectFilterFormTargets(uid, transaction) {
    var _a;
    const blockGrid = await this.findOwningBlockGrid(uid, transaction);
    if (!(blockGrid == null ? void 0 : blockGrid.uid)) {
      return [];
    }
    return import_lodash.default.castArray(((_a = blockGrid.subModels) == null ? void 0 : _a.items) || []).filter((item) => FILTER_TARGET_BLOCK_USES.has(item == null ? void 0 : item.use) && (item == null ? void 0 : item.uid)).map((item) => {
      var _a2, _b;
      const resourceInit = import_lodash.default.get(item, ["stepParams", "resourceSettings", "init"]) || ((item == null ? void 0 : item.use) === "ChartBlockModel" ? (0, import_chart_config.getChartBuilderResourceInit)(import_lodash.default.get(item, ["stepParams", "chartSettings", "configure"])) : null);
      if (!(resourceInit == null ? void 0 : resourceInit.dataSourceKey) || !(resourceInit == null ? void 0 : resourceInit.collectionName)) {
        return null;
      }
      const collection = this.options.getCollection(resourceInit.dataSourceKey, resourceInit.collectionName);
      return {
        ownerUid: item.uid,
        label: import_lodash.default.get(item, ["stepParams", "cardSettings", "titleDescription", "title"]) || ((_a2 = item == null ? void 0 : item.decoratorProps) == null ? void 0 : _a2.title) || ((_b = item == null ? void 0 : item.props) == null ? void 0 : _b.title) || (collection == null ? void 0 : collection.title) || (collection == null ? void 0 : collection.name) || item.uid,
        resourceInit
      };
    }).filter(Boolean);
  }
  async resolveBlockParent(target, transaction) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
    const resolved = await this.locator.resolve(target, { transaction });
    const node = resolved.node || await this.repository.findModelById(resolved.uid, { transaction, includeAsyncNode: true });
    const normalizedUse = (0, import_approval.normalizeApprovalSemanticUse)(node == null ? void 0 : node.use);
    if ((_a = node == null ? void 0 : node.use) == null ? void 0 : _a.endsWith("GridModel")) {
      if ((0, import_approval.isApprovalTaskCardGridUse)(node.use)) {
        (0, import_errors.throwBadRequest)(`flowSurfaces addBlock target '${node.use}' does not support blocks`);
      }
      return {
        parentUid: node.uid,
        subKey: "items",
        subType: "array"
      };
    }
    if (normalizedUse === "ChildPageTabModel") {
      return {
        parentUid: ((_c = (_b = node == null ? void 0 : node.subModels) == null ? void 0 : _b.grid) == null ? void 0 : _c.uid) || await this.options.ensureGridChild(node.uid, getDefaultGridUse(node.use, "BlockGridModel"), transaction),
        subKey: "items",
        subType: "array"
      };
    }
    if (normalizedUse === "ChildPageModel") {
      const firstTab = import_lodash.default.castArray(((_d = node == null ? void 0 : node.subModels) == null ? void 0 : _d.tabs) || [])[0];
      if (!(firstTab == null ? void 0 : firstTab.uid)) {
        (0, import_errors.throwBadRequest)(`flowSurfaces addBlock target '${node.use}' is missing its popup tab subtree`);
      }
      return {
        parentUid: ((_f = (_e = firstTab == null ? void 0 : firstTab.subModels) == null ? void 0 : _e.grid) == null ? void 0 : _f.uid) || await this.options.ensureGridChild(
          firstTab.uid,
          getDefaultGridUse(firstTab.use, "BlockGridModel"),
          transaction
        ),
        subKey: "items",
        subType: "array"
      };
    }
    if ((0, import_placement.isPopupHostUse)(node == null ? void 0 : node.use) || (0, import_approval.normalizeApprovalSemanticUse)((_h = (_g = node == null ? void 0 : node.subModels) == null ? void 0 : _g.page) == null ? void 0 : _h.use) === "ChildPageModel") {
      const popupSurface = await this.options.ensurePopupSurface(node.uid, transaction);
      return {
        parentUid: popupSurface.gridUid,
        subKey: "items",
        subType: "array",
        popupSurface
      };
    }
    if ((0, import_placement.isTabsRouteType)(resolved.tabRoute) || (node == null ? void 0 : node.use) === "RouteModel" && (0, import_placement.isTabsRouteType)(resolved.route)) {
      return {
        parentUid: ((_j = (_i = node == null ? void 0 : node.subModels) == null ? void 0 : _i.grid) == null ? void 0 : _j.uid) || await this.options.ensureGridChild(
          ((_l = (_k = resolved.tabRoute) == null ? void 0 : _k.get) == null ? void 0 : _l.call(_k, "schemaUid")) || node.uid,
          getDefaultGridUse(node == null ? void 0 : node.use, "BlockGridModel"),
          transaction
        ),
        subKey: "items",
        subType: "array"
      };
    }
    if ((0, import_placement.isPageRouteType)(resolved.pageRoute)) {
      const pageRoute = await this.options.hydrateRoute(resolved.pageRoute, transaction);
      const firstTab = import_lodash.default.sortBy(
        import_lodash.default.castArray(((_m = pageRoute == null ? void 0 : pageRoute.get) == null ? void 0 : _m.call(pageRoute, "children")) || (pageRoute == null ? void 0 : pageRoute.children) || []).map((item) => {
          var _a2;
          return ((_a2 = item == null ? void 0 : item.toJSON) == null ? void 0 : _a2.call(item)) || item;
        }),
        "sort"
      )[0];
      if (!(firstTab == null ? void 0 : firstTab.schemaUid)) {
        (0, import_errors.throwBadRequest)("flowSurfaces addBlock requires a tab under page");
      }
      return this.resolveBlockParent({ uid: firstTab.schemaUid }, transaction);
    }
    (0, import_errors.throwBadRequest)(`flowSurfaces addBlock target '${(node == null ? void 0 : node.use) || resolved.uid}' is not a grid surface`);
  }
  async resolveFieldContainer(uid, transaction) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
    const target = await this.locator.resolve({ uid }, { transaction });
    const node = target.node || await this.repository.findModelById(uid, { transaction, includeAsyncNode: true });
    const use = node == null ? void 0 : node.use;
    const normalizedUse = (0, import_approval.normalizeApprovalSemanticUse)(use);
    if ((0, import_placement.isFormBlockUse)(use)) {
      return {
        ownerUid: node.uid,
        ownerUse: use,
        parentUid: ((_b = (_a = node.subModels) == null ? void 0 : _a.grid) == null ? void 0 : _b.uid) || await this.options.ensureGridChild(node.uid, getDefaultGridUse(use, "FormGridModel"), transaction),
        subKey: "items",
        subType: "array",
        wrapperUse: getFieldWrapperUse(use, "FormItemModel")
      };
    }
    if (normalizedUse === "FormGridModel") {
      const parentUid = await this.locator.findParentUid(node.uid, transaction);
      const parent = parentUid ? await this.repository.findModelById(parentUid, { transaction }) : null;
      return {
        ownerUid: (parent == null ? void 0 : parent.uid) || node.uid,
        ownerUse: (parent == null ? void 0 : parent.use) || use,
        parentUid: node.uid,
        subKey: "items",
        subType: "array",
        wrapperUse: getFieldWrapperUse((parent == null ? void 0 : parent.use) || use, "FormItemModel")
      };
    }
    if ((0, import_placement.isDetailsBlockUse)(use)) {
      return {
        ownerUid: node.uid,
        ownerUse: use,
        parentUid: ((_d = (_c = node.subModels) == null ? void 0 : _c.grid) == null ? void 0 : _d.uid) || await this.options.ensureGridChild(node.uid, getDefaultGridUse(use, "DetailsGridModel"), transaction),
        subKey: "items",
        subType: "array",
        wrapperUse: getFieldWrapperUse(use, "DetailsItemModel")
      };
    }
    if (DETAILS_CARD_BLOCK_USES.has(use)) {
      const itemUid = (_f = (_e = node.subModels) == null ? void 0 : _e.item) == null ? void 0 : _f.uid;
      if (!itemUid) {
        (0, import_errors.throwBadRequest)(`flowSurfaces addField target '${use}' is missing its item subtree`);
      }
      return {
        ownerUid: node.uid,
        ownerUse: use,
        parentUid: ((_j = (_i = (_h = (_g = node.subModels) == null ? void 0 : _g.item) == null ? void 0 : _h.subModels) == null ? void 0 : _i.grid) == null ? void 0 : _j.uid) || await this.options.ensureGridChild(itemUid, "DetailsGridModel", transaction),
        subKey: "items",
        subType: "array",
        wrapperUse: "DetailsItemModel"
      };
    }
    if (DETAILS_CARD_ITEM_USES.has(use)) {
      return {
        ownerUid: node.uid,
        ownerUse: use,
        parentUid: ((_l = (_k = node.subModels) == null ? void 0 : _k.grid) == null ? void 0 : _l.uid) || await this.options.ensureGridChild(node.uid, "DetailsGridModel", transaction),
        subKey: "items",
        subType: "array",
        wrapperUse: "DetailsItemModel"
      };
    }
    if (normalizedUse === "DetailsGridModel") {
      const parentUid = await this.locator.findParentUid(node.uid, transaction);
      const parent = parentUid ? await this.repository.findModelById(parentUid, { transaction }) : null;
      return {
        ownerUid: (parent == null ? void 0 : parent.uid) || node.uid,
        ownerUse: (parent == null ? void 0 : parent.use) || use,
        parentUid: node.uid,
        subKey: "items",
        subType: "array",
        wrapperUse: getFieldWrapperUse((parent == null ? void 0 : parent.use) || use, "DetailsItemModel")
      };
    }
    if ((0, import_placement.isFilterFormBlockUse)(use)) {
      return {
        ownerUid: node.uid,
        ownerUse: use,
        parentUid: ((_n = (_m = node.subModels) == null ? void 0 : _m.grid) == null ? void 0 : _n.uid) || await this.options.ensureGridChild(node.uid, "FilterFormGridModel", transaction),
        subKey: "items",
        subType: "array",
        wrapperUse: "FilterFormItemModel"
      };
    }
    if (use === "FilterFormGridModel") {
      const parentUid = await this.locator.findParentUid(node.uid, transaction);
      const parent = parentUid ? await this.repository.findModelById(parentUid, { transaction }) : null;
      return {
        ownerUid: (parent == null ? void 0 : parent.uid) || node.uid,
        ownerUse: (parent == null ? void 0 : parent.use) || use,
        parentUid: node.uid,
        subKey: "items",
        subType: "array",
        wrapperUse: "FilterFormItemModel"
      };
    }
    if (use === "TableBlockModel") {
      return {
        ownerUid: node.uid,
        ownerUse: use,
        parentUid: node.uid,
        subKey: "columns",
        subType: "array",
        wrapperUse: "TableColumnModel"
      };
    }
    (0, import_errors.throwBadRequest)(`flowSurfaces addField target '${use || uid}' is not a field container`);
  }
  async resolveActionContainer(target, transaction) {
    var _a;
    const resolved = await this.locator.resolve(target, { transaction });
    const node = resolved.node || await this.repository.findModelById(resolved.uid, { transaction, includeAsyncNode: true });
    if ((0, import_action_scope.getActionContainerScope)(node == null ? void 0 : node.use) || (0, import_placement.isFormBlockUse)(node == null ? void 0 : node.use) || (0, import_placement.isDetailsBlockUse)(node == null ? void 0 : node.use) || (0, import_placement.isFilterFormBlockUse)(node == null ? void 0 : node.use)) {
      return {
        parentUid: node.uid,
        subKey: "actions",
        subType: "array",
        ownerUid: node.uid,
        ownerUse: node.use
      };
    }
    if ((_a = node == null ? void 0 : node.subModels) == null ? void 0 : _a.actions) {
      return {
        parentUid: node.uid,
        subKey: "actions",
        subType: "array",
        ownerUid: node.uid,
        ownerUse: node.use
      };
    }
    (0, import_errors.throwBadRequest)(`flowSurfaces addAction target '${(node == null ? void 0 : node.use) || resolved.uid}' is not an action container`);
  }
  async resolveGridNode(uid, transaction) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
    const resolved = await this.locator.resolve({ uid }, { transaction });
    const node = resolved.node || await this.repository.findModelById(uid, { transaction, includeAsyncNode: true });
    const normalizedUse = (0, import_approval.normalizeApprovalSemanticUse)(node == null ? void 0 : node.use);
    if ((_a = node == null ? void 0 : node.use) == null ? void 0 : _a.endsWith("GridModel")) {
      return node;
    }
    if ((((_c = (_b = resolved.tabRoute) == null ? void 0 : _b.get) == null ? void 0 : _c.call(_b, "type")) === "tabs" || ((_e = (_d = resolved.route) == null ? void 0 : _d.get) == null ? void 0 : _e.call(_d, "type")) === "tabs") && (node == null ? void 0 : node.use) === "RouteModel") {
      return this.repository.findModelById(
        ((_g = (_f = node == null ? void 0 : node.subModels) == null ? void 0 : _f.grid) == null ? void 0 : _g.uid) || await this.options.ensureGridChild(
          ((_i = (_h = resolved.tabRoute) == null ? void 0 : _h.get) == null ? void 0 : _i.call(_h, "schemaUid")) || node.uid,
          getDefaultGridUse(node == null ? void 0 : node.use, "BlockGridModel"),
          transaction
        ),
        { transaction, includeAsyncNode: true }
      );
    }
    if ((_k = (_j = node == null ? void 0 : node.subModels) == null ? void 0 : _j.grid) == null ? void 0 : _k.uid) {
      return this.repository.findModelById(node.subModels.grid.uid, { transaction, includeAsyncNode: true });
    }
    if (normalizedUse === "ChildPageTabModel") {
      return this.repository.findModelById(
        await this.options.ensureGridChild(node.uid, getDefaultGridUse(node == null ? void 0 : node.use, "BlockGridModel"), transaction),
        { transaction, includeAsyncNode: true }
      );
    }
    if (normalizedUse === "ChildPageModel") {
      const firstTab = import_lodash.default.castArray(((_l = node == null ? void 0 : node.subModels) == null ? void 0 : _l.tabs) || [])[0];
      if (!(firstTab == null ? void 0 : firstTab.uid)) {
        (0, import_errors.throwBadRequest)(`flowSurfaces setLayout target '${uid}' is missing its popup tab subtree`);
      }
      const gridUid = ((_n = (_m = firstTab == null ? void 0 : firstTab.subModels) == null ? void 0 : _m.grid) == null ? void 0 : _n.uid) || await this.options.ensureGridChild(
        firstTab.uid,
        getDefaultGridUse(firstTab.use, "BlockGridModel"),
        transaction
      );
      return this.repository.findModelById(gridUid, { transaction, includeAsyncNode: true });
    }
    if ((0, import_placement.isFormBlockUse)(node == null ? void 0 : node.use)) {
      return this.repository.findModelById(
        await this.options.ensureGridChild(node.uid, getDefaultGridUse(node == null ? void 0 : node.use, "FormGridModel"), transaction),
        { transaction, includeAsyncNode: true }
      );
    }
    if ((0, import_placement.isDetailsBlockUse)(node == null ? void 0 : node.use)) {
      return this.repository.findModelById(
        await this.options.ensureGridChild(node.uid, getDefaultGridUse(node == null ? void 0 : node.use, "DetailsGridModel"), transaction),
        { transaction, includeAsyncNode: true }
      );
    }
    if ((0, import_placement.isFilterFormBlockUse)(node == null ? void 0 : node.use)) {
      return this.repository.findModelById(
        await this.options.ensureGridChild(node.uid, "FilterFormGridModel", transaction),
        { transaction, includeAsyncNode: true }
      );
    }
    (0, import_errors.throwBadRequest)(`flowSurfaces setLayout target '${uid}' is not a grid node`);
  }
  async findOwningBlockGrid(uid, transaction) {
    let cursor = uid;
    while (cursor) {
      const node = await this.repository.findModelById(cursor, { transaction, includeAsyncNode: true });
      if ((0, import_approval.normalizeApprovalSemanticUse)(node == null ? void 0 : node.use) === "BlockGridModel") {
        return node;
      }
      cursor = await this.locator.findParentUid(cursor, transaction);
    }
    return null;
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  FlowSurfaceContextResolver
});
