/**
 * 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 __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var resolver_exports = {};
__export(resolver_exports, {
  findReactionTargetNodeInReadback: () => findReactionTargetNodeInReadback,
  resolveReactionCapability: () => resolveReactionCapability,
  resolveReactionStorageNode: () => resolveReactionStorageNode,
  resolveReactionTarget: () => resolveReactionTarget,
  resolveReactionTargetFromReadback: () => resolveReactionTargetFromReadback
});
module.exports = __toCommonJS(resolver_exports);
var import_errors = require("../errors");
var import_errors2 = require("./errors");
var import_registry = require("./registry");
const FORM_REACTION_USES = /* @__PURE__ */ new Set(["CreateFormModel", "EditFormModel", "FormBlockModel"]);
const DETAILS_REACTION_USES = /* @__PURE__ */ new Set(["DetailsBlockModel"]);
const SUB_FORM_REACTION_USES = /* @__PURE__ */ new Set(["SubFormFieldModel", "SubFormListFieldModel"]);
const FORM_GRID_STORAGE_KINDS = /* @__PURE__ */ new Set(["fieldValue", "fieldLinkage"]);
function normalizeTargetUid(input) {
  const uid = String((input == null ? void 0 : input.uid) || "").trim();
  if (!uid) {
    (0, import_errors.throwBadRequest)("flowSurfaces reaction requires target.uid");
  }
  return uid;
}
function inferReactionTargetKind(use, supportedKinds) {
  if (SUB_FORM_REACTION_USES.has(use || "")) {
    return "fieldHost";
  }
  if (supportedKinds.includes("actionLinkage") && supportedKinds.length === 1) {
    return "action";
  }
  return "block";
}
function inferReactionScene(kind, use) {
  switch (kind) {
    case "fieldValue":
      return FORM_REACTION_USES.has(use || "") ? "form" : void 0;
    case "blockLinkage":
      return "block";
    case "actionLinkage":
      return "action";
    case "fieldLinkage":
      if (FORM_REACTION_USES.has(use || "")) {
        return "form";
      }
      if (DETAILS_REACTION_USES.has(use || "")) {
        return "details";
      }
      if (SUB_FORM_REACTION_USES.has(use || "")) {
        return "subForm";
      }
      return void 0;
    default:
      return void 0;
  }
}
function buildUnsupportedTargetMessage(kind, use) {
  if (kind === "fieldValue") {
    return "flowSurfaces reaction field values are only available on create/edit form blocks";
  }
  return `flowSurfaces reaction target '${use || "unknown"}' does not support ${kind}`;
}
function findReactionTargetNodeInReadback(readback, uid) {
  var _a;
  const normalizedUid = String(uid || "").trim();
  if (!normalizedUid) {
    return void 0;
  }
  const visit = (node) => {
    if (!node || typeof node !== "object") {
      return void 0;
    }
    if (node.uid === normalizedUid) {
      return node;
    }
    for (const child of Object.values(node.subModels || {})) {
      const children = Array.isArray(child) ? child : [child];
      for (const item of children) {
        const matched = visit(item);
        if (matched) {
          return matched;
        }
      }
    }
    return void 0;
  };
  return visit(readback == null ? void 0 : readback.tree) || ((_a = readback == null ? void 0 : readback.nodeMap) == null ? void 0 : _a[normalizedUid]);
}
function resolveReactionTarget(values) {
  const uid = normalizeTargetUid(values.target);
  const node = values.node || {};
  const use = String(values.use || (node == null ? void 0 : node.use) || "").trim() || void 0;
  const supportedKinds = (0, import_registry.getReactionKindsForUse)(use);
  if (!supportedKinds.length) {
    (0, import_errors.throwBadRequest)(
      `flowSurfaces reaction target '${use || uid}' does not support advanced reaction capabilities`,
      import_errors2.FLOW_SURFACE_REACTION_UNSUPPORTED_TARGET_KIND
    );
  }
  const capabilities = supportedKinds.map((kind) => {
    const resolvedScene = inferReactionScene(kind, use);
    if (!resolvedScene) {
      (0, import_errors.throwBadRequest)(
        `flowSurfaces reaction target '${use || uid}' cannot uniquely resolve scene for ${kind}`,
        import_errors2.FLOW_SURFACE_REACTION_AMBIGUOUS_SCENE
      );
    }
    const resolvedSlot = (0, import_registry.getReactionSlot)(kind, resolvedScene);
    if (!resolvedSlot) {
      (0, import_errors.throwBadRequest)(
        `flowSurfaces reaction target '${use || uid}' cannot resolve storage slot for ${kind}`,
        import_errors2.FLOW_SURFACE_REACTION_AMBIGUOUS_SCENE
      );
    }
    return {
      kind,
      resolvedScene,
      resolvedSlot
    };
  });
  return {
    target: {
      uid,
      publicPath: String(
        values.publicPath || ("publicPath" in values.target && typeof values.target.publicPath === "string" ? values.target.publicPath : "")
      ).trim() || void 0
    },
    node,
    use,
    targetKind: inferReactionTargetKind(use, supportedKinds),
    capabilities
  };
}
function resolveReactionTargetFromReadback(values) {
  const uid = normalizeTargetUid(values.target);
  const node = findReactionTargetNodeInReadback(values.readback, uid);
  return resolveReactionTarget({
    node,
    use: node == null ? void 0 : node.use,
    target: values.target,
    publicPath: values.publicPath
  });
}
function resolveReactionCapability(resolvedTarget, kind) {
  const matched = resolvedTarget.capabilities.find((item) => item.kind === kind);
  if (!matched) {
    (0, import_errors.throwBadRequest)(
      buildUnsupportedTargetMessage(kind, resolvedTarget.use),
      kind === "fieldValue" ? import_errors2.FLOW_SURFACE_REACTION_FORM_ONLY : import_errors2.FLOW_SURFACE_REACTION_UNSUPPORTED_TARGET_KIND
    );
  }
  return {
    ...resolvedTarget,
    ...matched
  };
}
function resolveReactionStorageNode(resolvedTarget, capability) {
  var _a, _b;
  if (FORM_REACTION_USES.has(resolvedTarget.use || "") && capability.resolvedScene === "form" && FORM_GRID_STORAGE_KINDS.has(capability.kind)) {
    const gridNode = (_b = (_a = resolvedTarget.node) == null ? void 0 : _a.subModels) == null ? void 0 : _b.grid;
    if (gridNode && typeof gridNode === "object" && String(gridNode.uid || "").trim()) {
      return gridNode;
    }
    (0, import_errors.throwBadRequest)(
      `flowSurfaces reaction target '${resolvedTarget.use || resolvedTarget.target.uid}' is missing form grid storage node for ${capability.kind}`
    );
  }
  return resolvedTarget.node;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  findReactionTargetNodeInReadback,
  resolveReactionCapability,
  resolveReactionStorageNode,
  resolveReactionTarget,
  resolveReactionTargetFromReadback
});
