/**
 * 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 template_display_exports = {};
__export(template_display_exports, {
  compileTemplateString: () => compileTemplateString,
  resolveFlowTemplateDisplayRow: () => resolveFlowTemplateDisplayRow,
  resolveFlowTemplateDisplayRows: () => resolveFlowTemplateDisplayRows
});
module.exports = __toCommonJS(template_display_exports);
var import_json_schema = require("@formily/json-schema");
var import_lodash = __toESM(require("lodash"));
var import_service_helpers = require("./service-helpers");
var import_service_utils = require("./service-utils");
const AUTO_GENERATED_SUFFIX = " (Auto generated)";
const LEGACY_AUTO_POPUP_PREFIX = "Auto popup ";
const LEGACY_AUTO_POPUP_DESCRIPTION_PREFIX = "Auto-generated popup template ";
function getFallbackTranslate() {
  return (key, options) => key.replace(/\{\{\s*([^}\s]+)\s*\}\}/g, (_match, name) => {
    const value = options == null ? void 0 : options[name];
    return import_lodash.default.isUndefined(value) || import_lodash.default.isNull(value) ? "" : String(value);
  });
}
function extractTranslationKey(tokenContent) {
  var _a;
  const matched = tokenContent.match(/["'`]([^"'`]+)["'`]/);
  return ((_a = matched == null ? void 0 : matched[1]) == null ? void 0 : _a.trim()) || "";
}
function sanitizePendingTranslationTokens(value) {
  if (!value.includes("{{")) {
    return value;
  }
  return value.replace(/\{\{\s*t\(([\s\S]*?)\)\s*\}\}/g, (_match, tokenContent) => extractTranslationKey(tokenContent));
}
function compileTemplateString(value, t) {
  if (typeof value !== "string" || !value) {
    return value;
  }
  try {
    const compiled = import_json_schema.Schema.compile(value, { t: t || getFallbackTranslate() });
    if (typeof compiled === "string") {
      return sanitizePendingTranslationTokens(compiled).trim();
    }
    return compiled;
  } catch (error) {
    return sanitizePendingTranslationTokens(value).trim();
  }
}
function inferPopupDefaultTypeFromTargetTree(node) {
  var _a, _b, _c, _d;
  const popupPage = (0, import_service_utils.getSingleNodeSubModel)((_a = node == null ? void 0 : node.subModels) == null ? void 0 : _a.page);
  const popupTab = import_lodash.default.castArray(((_b = popupPage == null ? void 0 : popupPage.subModels) == null ? void 0 : _b.tabs) || [])[0];
  const popupGrid = (0, import_service_utils.getSingleNodeSubModel)((_c = popupTab == null ? void 0 : popupTab.subModels) == null ? void 0 : _c.grid);
  const popupBlock = (0, import_service_utils.getNodeSubModelList)((_d = popupGrid == null ? void 0 : popupGrid.subModels) == null ? void 0 : _d.items)[0];
  if ((popupBlock == null ? void 0 : popupBlock.use) === "DetailsBlockModel") {
    return "view";
  }
  if ((popupBlock == null ? void 0 : popupBlock.use) === "EditFormModel") {
    return "edit";
  }
  if ((popupBlock == null ? void 0 : popupBlock.use) === "CreateFormModel") {
    return "addNew";
  }
  return "generic";
}
function getPopupLabelKey(defaultType) {
  switch (defaultType) {
    case "addNew":
      return "Popup for Add New";
    case "edit":
      return "Popup for Edit";
    case "view":
      return "Popup for Details";
    default:
      return "popup";
  }
}
function getAutoGeneratedDisplaySuffix(t) {
  const translate = t || getFallbackTranslate();
  return ` (${translate("Auto generated")})`;
}
function getUsableExplicitTitle(rawTitle) {
  if (!import_lodash.default.isString(rawTitle)) {
    return rawTitle;
  }
  const normalizedTitle = rawTitle.trim();
  if (!normalizedTitle) {
    return void 0;
  }
  return normalizedTitle;
}
function getExplicitCollectionTitle(collection) {
  var _a;
  return getUsableExplicitTitle(collection == null ? void 0 : collection.title) || getUsableExplicitTitle((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.title);
}
function getExplicitFieldTitle(field) {
  var _a, _b, _c, _d;
  return getUsableExplicitTitle((_a = field == null ? void 0 : field.uiSchema) == null ? void 0 : _a.title) || getUsableExplicitTitle((_c = (_b = field == null ? void 0 : field.options) == null ? void 0 : _b.uiSchema) == null ? void 0 : _c.title) || getUsableExplicitTitle(field == null ? void 0 : field.title) || getUsableExplicitTitle((_d = field == null ? void 0 : field.options) == null ? void 0 : _d.title);
}
function isAutoGeneratedPopupTemplateName(name) {
  return name.endsWith(AUTO_GENERATED_SUFFIX) || name.startsWith(LEGACY_AUTO_POPUP_PREFIX);
}
function isAutoGeneratedPopupTemplateDescription(description) {
  return description.startsWith(LEGACY_AUTO_POPUP_DESCRIPTION_PREFIX) || description.startsWith("Automatically generated popup template for ");
}
function buildAutoGeneratedActionPopupMetadata(input) {
  const translate = input.t || getFallbackTranslate();
  const popupLabel = translate(getPopupLabelKey(input.popupType));
  return {
    name: `${input.collectionLabel} ${popupLabel}${getAutoGeneratedDisplaySuffix(input.t)}`,
    description: translate(
      'Automatically generated popup template for collection "{{collectionLabel}}" ({{popupLabel}}). Scene: {{scene}}; collection: "{{collectionLabel}}".',
      {
        collectionLabel: input.collectionLabel,
        popupLabel,
        scene: input.popupType
      }
    )
  };
}
function buildAutoGeneratedAssociationPopupMetadata(input) {
  const translate = input.t || getFallbackTranslate();
  const popupLabel = translate(getPopupLabelKey(input.popupType));
  return {
    name: `${input.sourceCollectionLabel} -> ${input.associationFieldLabel} ${popupLabel}${getAutoGeneratedDisplaySuffix(input.t)}`,
    description: translate(
      'Automatically generated popup template for relation field "{{associationFieldLabel}}" in collection "{{sourceCollectionLabel}}", targeting "{{targetCollectionLabel}}" ({{popupLabel}}). Scene: {{scene}}; source collection: "{{sourceCollectionLabel}}"; association field: "{{associationFieldLabel}}"; target collection: "{{targetCollectionLabel}}".',
      {
        associationFieldLabel: input.associationFieldLabel,
        sourceCollectionLabel: input.sourceCollectionLabel,
        targetCollectionLabel: input.targetCollectionLabel,
        popupLabel,
        scene: input.popupType
      }
    )
  };
}
async function getTargetTree(db, targetUid, transaction) {
  var _a;
  const normalizedTargetUid = String(targetUid || "").trim();
  if (!normalizedTargetUid) {
    return null;
  }
  const repo = (_a = db.getCollection("flowModels")) == null ? void 0 : _a.repository;
  if (!repo) {
    return null;
  }
  return repo.findModelById(normalizedTargetUid, {
    transaction,
    includeAsyncNode: true
  });
}
function getCollection(db, dataSourceKey, collectionName) {
  var _a, _b, _c, _d, _e, _f, _g, _h;
  const normalizedDataSourceKey = dataSourceKey || "main";
  const mainCollection = normalizedDataSourceKey === "main" ? (_a = db.getCollection) == null ? void 0 : _a.call(db, collectionName) : null;
  if (mainCollection) {
    return mainCollection;
  }
  const dataSourceManager = ((_b = db.app) == null ? void 0 : _b.dataSourceManager) || db.dataSourceManager;
  const ds = ((_c = dataSourceManager == null ? void 0 : dataSourceManager.get) == null ? void 0 : _c.call(dataSourceManager, normalizedDataSourceKey)) || ((_e = (_d = dataSourceManager == null ? void 0 : dataSourceManager.dataSources) == null ? void 0 : _d.get) == null ? void 0 : _e.call(_d, normalizedDataSourceKey));
  return ((_g = (_f = ds == null ? void 0 : ds.collectionManager) == null ? void 0 : _f.getCollection) == null ? void 0 : _g.call(_f, collectionName)) || ((_h = db.getCollection) == null ? void 0 : _h.call(db, collectionName));
}
function parseAssociationSource(associationName) {
  const normalized = String(associationName || "").trim();
  if (!normalized || !normalized.includes(".")) {
    return null;
  }
  const parts = normalized.split(".").filter(Boolean);
  if (parts.length < 2) {
    return null;
  }
  return {
    sourceCollectionName: parts[0],
    associationFieldPath: parts.slice(1).join("."),
    associationFieldName: parts[parts.length - 1]
  };
}
function resolveAssociationPathField(input) {
  var _a, _b, _c;
  const parts = String(input.associationFieldPath || "").split(".").map((part) => part.trim()).filter(Boolean);
  let collection = input.sourceCollection;
  let field = null;
  for (const [index, part] of parts.entries()) {
    field = ((_a = collection == null ? void 0 : collection.getField) == null ? void 0 : _a.call(collection, part)) || ((_c = (_b = collection == null ? void 0 : collection.fields) == null ? void 0 : _b.get) == null ? void 0 : _c.call(_b, part)) || null;
    if (!field) {
      return {
        field: null,
        targetCollection: null
      };
    }
    if (index < parts.length - 1) {
      collection = (0, import_service_helpers.resolveFieldTargetCollection)(
        field,
        input.dataSourceKey,
        (dataSourceKey, collectionName) => getCollection(input.db, dataSourceKey, collectionName)
      );
      if (!collection) {
        return {
          field: null,
          targetCollection: null
        };
      }
    }
  }
  const targetCollection = field ? (0, import_service_helpers.resolveFieldTargetCollection)(
    field,
    input.dataSourceKey,
    (dataSourceKey, collectionName) => getCollection(input.db, dataSourceKey, collectionName)
  ) : null;
  return {
    field,
    targetCollection
  };
}
async function buildAutoGeneratedPopupMetadata(db, row, t, transaction) {
  var _a;
  const targetTree = await getTargetTree(db, row.targetUid, transaction);
  const popupType = inferPopupDefaultTypeFromTargetTree(targetTree);
  const dataSourceKey = String(row.dataSourceKey || "main").trim() || "main";
  const collectionName = String(row.collectionName || "").trim();
  const associationName = String(row.associationName || "").trim();
  const collection = getCollection(db, dataSourceKey, collectionName);
  const collectionLabel = String(
    compileTemplateString(getExplicitCollectionTitle(collection) || collectionName, t) || ""
  ).trim();
  if (associationName) {
    const associationSource = parseAssociationSource(associationName);
    const sourceCollectionName = (associationSource == null ? void 0 : associationSource.sourceCollectionName) || collectionName;
    const sourceCollection = getCollection(db, dataSourceKey, sourceCollectionName) || collection;
    const associationContext = resolveAssociationPathField({
      db,
      dataSourceKey,
      sourceCollection,
      associationFieldPath: associationSource == null ? void 0 : associationSource.associationFieldPath
    });
    const associationField = associationContext.field || ((_a = sourceCollection == null ? void 0 : sourceCollection.getField) == null ? void 0 : _a.call(sourceCollection, (associationSource == null ? void 0 : associationSource.associationFieldName) || ""));
    const targetCollectionName = String(
      (0, import_service_helpers.getFieldTarget)(associationField) || (0, import_service_helpers.getCollectionName)(associationContext.targetCollection) || collectionName || ""
    ).trim() || collectionName;
    const targetCollection = associationContext.targetCollection || getCollection(db, dataSourceKey, targetCollectionName) || collection;
    const sourceCollectionLabel = String(
      compileTemplateString(
        getExplicitCollectionTitle(sourceCollection) || (0, import_service_helpers.getCollectionName)(sourceCollection) || sourceCollectionName,
        t
      ) || ""
    ).trim();
    const associationFieldLabel = String(
      compileTemplateString(
        getExplicitFieldTitle(associationField) || (0, import_service_helpers.getFieldName)(associationField) || (associationSource == null ? void 0 : associationSource.associationFieldName) || "",
        t
      ) || ""
    ).trim();
    const targetCollectionLabel = String(
      compileTemplateString(
        getExplicitCollectionTitle(targetCollection) || (0, import_service_helpers.getCollectionName)(targetCollection) || targetCollectionName,
        t
      ) || ""
    ).trim();
    if (sourceCollectionLabel && associationFieldLabel && targetCollectionLabel) {
      return buildAutoGeneratedAssociationPopupMetadata({
        popupType,
        sourceCollectionLabel,
        associationFieldLabel,
        targetCollectionLabel,
        t
      });
    }
  }
  if (collectionLabel) {
    return buildAutoGeneratedActionPopupMetadata({
      popupType,
      collectionLabel,
      t
    });
  }
  return null;
}
async function resolveFlowTemplateDisplayRow(db, row, options = {}) {
  const plainRow = typeof (row == null ? void 0 : row.toJSON) === "function" ? row.toJSON() : row;
  if (!plainRow) {
    return plainRow;
  }
  const t = options.t || getFallbackTranslate();
  const nextRow = {
    ...plainRow,
    name: compileTemplateString(plainRow.name, t),
    description: compileTemplateString(plainRow.description, t)
  };
  const hasAutoGeneratedName = isAutoGeneratedPopupTemplateName(String(nextRow.name || "").trim());
  const hasAutoGeneratedDescription = isAutoGeneratedPopupTemplateDescription(String(nextRow.description || "").trim());
  if (String(nextRow.type || "").trim() !== "popup" || !hasAutoGeneratedName && !hasAutoGeneratedDescription) {
    return nextRow;
  }
  const rewritten = await buildAutoGeneratedPopupMetadata(db, nextRow, t, options.transaction);
  if (!rewritten) {
    return nextRow;
  }
  return {
    ...nextRow,
    name: hasAutoGeneratedName ? rewritten.name : nextRow.name,
    description: hasAutoGeneratedDescription ? rewritten.description : nextRow.description
  };
}
async function resolveFlowTemplateDisplayRows(db, rows, options = {}) {
  return Promise.all(rows.map((row) => resolveFlowTemplateDisplayRow(db, row, options)));
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  compileTemplateString,
  resolveFlowTemplateDisplayRow,
  resolveFlowTemplateDisplayRows
});
