/**
 * 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 service_helpers_exports = {};
__export(service_helpers_exports, {
  buildCatalogCollectionCycleKey: () => buildCatalogCollectionCycleKey,
  buildFilterFieldMeta: () => buildFilterFieldMeta,
  buildFlowTemplateSearchFilter: () => buildFlowTemplateSearchFilter,
  dedupeVisibleFieldCandidates: () => dedupeVisibleFieldCandidates,
  formatChartBuilderSupportedRelationSubfields: () => formatChartBuilderSupportedRelationSubfields,
  getAssociationFilterTargetKey: () => getAssociationFilterTargetKey,
  getChartBuilderSupportedRelationSubfields: () => getChartBuilderSupportedRelationSubfields,
  getCollectionFields: () => getCollectionFields,
  getCollectionModelAttributes: () => getCollectionModelAttributes,
  getCollectionName: () => getCollectionName,
  getCollectionTitle: () => getCollectionTitle,
  getCollectionTitleFieldName: () => getCollectionTitleFieldName,
  getFieldFilterable: () => getFieldFilterable,
  getFieldInterface: () => getFieldInterface,
  getFieldName: () => getFieldName,
  getFieldTarget: () => getFieldTarget,
  getFieldTitle: () => getFieldTitle,
  getFieldType: () => getFieldType,
  getInvalidChartBuilderRelationDirectSubfieldDetails: () => getInvalidChartBuilderRelationDirectSubfieldDetails,
  getUnsupportedChartBuilderRelationSubfieldDetails: () => getUnsupportedChartBuilderRelationSubfieldDetails,
  hasConfiguredFlowContextValue: () => hasConfiguredFlowContextValue,
  inferAssociationLeafDisplayFieldUse: () => inferAssociationLeafDisplayFieldUse,
  inferFieldMenuEditableFieldUse: () => inferFieldMenuEditableFieldUse,
  inferFlowContextTypeFromField: () => inferFlowContextTypeFromField,
  isAssociationField: () => isAssociationField,
  normalizeFieldPath: () => normalizeFieldPath,
  normalizeTemplatePage: () => normalizeTemplatePage,
  normalizeTemplatePageSize: () => normalizeTemplatePageSize,
  resolveAssociationNameFromField: () => resolveAssociationNameFromField,
  resolveFieldFromCollection: () => resolveFieldFromCollection,
  resolveFieldTargetCollection: () => resolveFieldTargetCollection,
  toTemplatePlainRow: () => toTemplatePlainRow
});
module.exports = __toCommonJS(service_helpers_exports);
var import_lodash = __toESM(require("lodash"));
var import_core_field_default_bindings = require("./core-field-default-bindings");
const FLOW_SURFACE_TEMPLATE_DEFAULT_PAGE = 1;
const FLOW_SURFACE_TEMPLATE_DEFAULT_PAGE_SIZE = 50;
const ASSOCIATION_FIELD_TYPES = /* @__PURE__ */ new Set([
  "belongsto",
  "hasone",
  "hasmany",
  "belongstomany",
  "belongstoarray",
  "onetoone"
]);
const ASSOCIATION_FIELD_INTERFACES = /* @__PURE__ */ new Set([
  "m2o",
  "o2m",
  "m2m",
  "o2o",
  "mbm",
  "obo",
  "oho",
  "manytoone",
  "onetomany",
  "manytomany"
]);
function toTemplatePlainRow(row) {
  if (!row) {
    return row;
  }
  if (typeof row.toJSON === "function") {
    return row.toJSON();
  }
  return row;
}
function buildFlowTemplateSearchFilter(existing, search) {
  const filters = [];
  if (existing) {
    filters.push(existing);
  }
  const normalizedSearch = String(search || "").trim();
  if (normalizedSearch) {
    filters.push({
      $or: [{ name: { $includes: normalizedSearch } }, { description: { $includes: normalizedSearch } }]
    });
  }
  if (!filters.length) {
    return void 0;
  }
  if (filters.length === 1) {
    return filters[0];
  }
  return { $and: filters };
}
function normalizeTemplatePage(value) {
  const num = Number(value || FLOW_SURFACE_TEMPLATE_DEFAULT_PAGE);
  if (!Number.isFinite(num) || num < 1) {
    return FLOW_SURFACE_TEMPLATE_DEFAULT_PAGE;
  }
  return Math.floor(num);
}
function normalizeTemplatePageSize(value) {
  const num = Number(value || FLOW_SURFACE_TEMPLATE_DEFAULT_PAGE_SIZE);
  if (!Number.isFinite(num) || num < 1) {
    return FLOW_SURFACE_TEMPLATE_DEFAULT_PAGE_SIZE;
  }
  return Math.floor(num);
}
function normalizeFieldPath(fieldPath, associationPathName) {
  const normalizedFieldPath = String(fieldPath || "").trim();
  const normalizedAssociationPath = String(associationPathName || "").trim();
  if (!normalizedAssociationPath || !normalizedFieldPath || normalizedFieldPath.includes(".")) {
    return normalizedFieldPath;
  }
  return `${normalizedAssociationPath}.${normalizedFieldPath}`;
}
function hasConfiguredFlowContextValue(value) {
  return !import_lodash.default.isNil(value) && value !== "";
}
function buildFilterFieldMeta(field) {
  return import_lodash.default.pickBy(
    {
      name: getFieldName(field),
      title: getFieldTitle(field),
      interface: getFieldInterface(field),
      type: getFieldType(field)
    },
    (value) => !import_lodash.default.isUndefined(value)
  );
}
function getCollectionFields(collection) {
  var _a, _b, _c;
  return import_lodash.default.castArray(((_a = collection == null ? void 0 : collection.getFields) == null ? void 0 : _a.call(collection)) || Array.from(((_c = (_b = collection == null ? void 0 : collection.fields) == null ? void 0 : _b.values) == null ? void 0 : _c.call(_b)) || []));
}
function getCollectionTitle(collection) {
  var _a, _b;
  return (collection == null ? void 0 : collection.title) || ((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.title) || (collection == null ? void 0 : collection.name) || ((_b = collection == null ? void 0 : collection.options) == null ? void 0 : _b.name);
}
function getCollectionName(collection) {
  var _a;
  return (collection == null ? void 0 : collection.name) || ((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.name);
}
function getCollectionTitleFieldName(collection) {
  var _a, _b, _c, _d, _e;
  const filterTargetKey = (collection == null ? void 0 : collection.filterTargetKey) || ((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.filterTargetKey);
  return ((_b = collection == null ? void 0 : collection.options) == null ? void 0 : _b.titleField) || ((_c = collection == null ? void 0 : collection.titleCollectionField) == null ? void 0 : _c.name) || ((_e = (_d = collection == null ? void 0 : collection.titleCollectionField) == null ? void 0 : _d.options) == null ? void 0 : _e.name) || (Array.isArray(filterTargetKey) ? filterTargetKey[0] : filterTargetKey) || (collection == null ? void 0 : collection.titleField);
}
function getFieldName(field) {
  var _a;
  return (field == null ? void 0 : field.name) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.name);
}
function getFieldTitle(field) {
  var _a, _b, _c, _d;
  return ((_a = field == null ? void 0 : field.uiSchema) == null ? void 0 : _a.title) || ((_c = (_b = field == null ? void 0 : field.options) == null ? void 0 : _b.uiSchema) == null ? void 0 : _c.title) || (field == null ? void 0 : field.title) || ((_d = field == null ? void 0 : field.options) == null ? void 0 : _d.title) || getFieldName(field);
}
function getCollectionModelAttributes(collection) {
  var _a, _b, _c;
  return (typeof ((_a = collection == null ? void 0 : collection.model) == null ? void 0 : _a.getAttributes) === "function" ? collection.model.getAttributes() : null) || ((_b = collection == null ? void 0 : collection.model) == null ? void 0 : _b.rawAttributes) || ((_c = collection == null ? void 0 : collection.model) == null ? void 0 : _c.attributes) || {};
}
function getCollectionFieldColumnName(collection, fieldName) {
  var _a;
  const normalized = String(fieldName || "").trim();
  if (!normalized) {
    return "";
  }
  const attribute = (_a = getCollectionModelAttributes(collection)) == null ? void 0 : _a[normalized];
  return String((attribute == null ? void 0 : attribute.field) || normalized).trim();
}
function getChartBuilderSupportedRelationSubfields(associationPathName, targetCollection) {
  const normalizedAssociationPath = String(associationPathName || "").trim();
  if (!normalizedAssociationPath || !targetCollection) {
    return [];
  }
  return getCollectionFields(targetCollection).reduce((result, field) => {
    const fieldName = getFieldName(field);
    if (!fieldName || isAssociationField(field)) {
      return result;
    }
    if (getCollectionFieldColumnName(targetCollection, fieldName) !== fieldName) {
      return result;
    }
    result.push(
      import_lodash.default.pickBy(
        {
          field: `${normalizedAssociationPath}.${fieldName}`,
          title: getFieldTitle(field),
          interface: getFieldInterface(field)
        },
        (value) => !import_lodash.default.isUndefined(value)
      )
    );
    return result;
  }, []);
}
function formatChartBuilderSupportedRelationSubfields(associationPath, supportedFields = []) {
  const fields = supportedFields.map((item) => String((item == null ? void 0 : item.field) || "").trim()).filter(Boolean);
  if (!fields.length) {
    return `No chart-builder-compatible fields are available under '${associationPath}'.`;
  }
  return `Supported fields under '${associationPath}': ${fields.join(", ")}.`;
}
function getInvalidChartBuilderRelationDirectSubfieldDetails(input) {
  const associationPath = String(input.associationPathName || "").trim();
  const selectedSubfieldPath = String(input.selectedSubfieldPath || "").trim();
  const selectedParts = selectedSubfieldPath.split(".").filter(Boolean);
  if (!associationPath || !input.targetCollection || !selectedParts.length) {
    return null;
  }
  const leafFieldName = selectedParts[0];
  const leafField = resolveFieldFromCollection(input.targetCollection, leafFieldName);
  const modelAttributes = getCollectionModelAttributes(input.targetCollection);
  const modelAttribute = modelAttributes == null ? void 0 : modelAttributes[leafFieldName];
  const hasModelAttribute = Object.prototype.hasOwnProperty.call(modelAttributes, leafFieldName);
  const hasNestedSubfieldPath = selectedParts.length > 1;
  if (leafField && !hasNestedSubfieldPath && !isAssociationField(leafField)) {
    return null;
  }
  if (!leafField && hasModelAttribute && !hasNestedSubfieldPath) {
    const columnName = String((modelAttribute == null ? void 0 : modelAttribute.field) || leafFieldName).trim();
    if (columnName && columnName !== leafFieldName) {
      return null;
    }
  }
  return {
    associationPath,
    leafFieldName,
    selectedSubfieldPath: selectedParts.join("."),
    supportedFields: getChartBuilderSupportedRelationSubfields(associationPath, input.targetCollection)
  };
}
function getUnsupportedChartBuilderRelationSubfieldDetails(input) {
  const leafFieldName = String(input.leafFieldName || "").trim();
  if (!input.targetCollection || !leafFieldName || input.leafField && isAssociationField(input.leafField)) {
    return null;
  }
  const modelAttributes = getCollectionModelAttributes(input.targetCollection);
  if (!input.leafField && !Object.prototype.hasOwnProperty.call(modelAttributes, leafFieldName)) {
    return null;
  }
  const columnName = getCollectionFieldColumnName(input.targetCollection, leafFieldName);
  if (!columnName || columnName === leafFieldName) {
    return null;
  }
  return {
    associationPath: String(input.associationPathName || "").trim(),
    leafFieldName,
    columnName,
    supportedFields: getChartBuilderSupportedRelationSubfields(input.associationPathName, input.targetCollection)
  };
}
function resolveAssociationNameFromField(field, fallbackCollection) {
  const resourceName = typeof (field == null ? void 0 : field.resourceName) === "string" ? field.resourceName.trim() : "";
  if (resourceName) {
    return resourceName;
  }
  const fieldName = getFieldName(field);
  if (!fieldName) {
    return void 0;
  }
  const sourceCollectionName = getCollectionName(field == null ? void 0 : field.collection) || getCollectionName(fallbackCollection);
  return sourceCollectionName ? `${sourceCollectionName}.${fieldName}` : void 0;
}
function getFieldInterface(field) {
  var _a;
  return (field == null ? void 0 : field.interface) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.interface);
}
function getFieldType(field) {
  var _a;
  return (field == null ? void 0 : field.type) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.type);
}
function inferFlowContextTypeFromField(field) {
  switch (getFieldType(field)) {
    case "boolean":
      return "boolean";
    case "integer":
    case "float":
    case "double":
    case "decimal":
      return "number";
    case "json":
      return "object";
    case "array":
      return "array";
    default:
      return "string";
  }
}
function getFieldTarget(field) {
  var _a;
  return (field == null ? void 0 : field.target) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.target);
}
function getFieldFilterable(field) {
  var _a;
  if (!import_lodash.default.isUndefined(field == null ? void 0 : field.filterable)) {
    return field.filterable;
  }
  return (_a = field == null ? void 0 : field.options) == null ? void 0 : _a.filterable;
}
function inferAssociationLeafDisplayFieldUse(fieldInterface) {
  return (0, import_core_field_default_bindings.getSharedFieldDefaultBindingUse)("display", fieldInterface);
}
function inferFieldMenuEditableFieldUse(fieldInterface) {
  const normalized = String(fieldInterface || "").trim();
  if (["m2m", "m2o", "o2o", "o2m", "oho", "obo", "updatedBy", "createdBy", "mbm"].includes(normalized)) {
    return "RecordSelectFieldModel";
  }
  return (0, import_core_field_default_bindings.getSharedFieldDefaultBindingUse)("editable", normalized);
}
function isAssociationField(field) {
  if (typeof (field == null ? void 0 : field.isAssociationField) === "function") {
    return field.isAssociationField();
  }
  if (getFieldTarget(field)) {
    return true;
  }
  const fieldType = String(getFieldType(field) || "").trim().toLowerCase();
  const fieldInterface = String(getFieldInterface(field) || "").trim().toLowerCase();
  return ASSOCIATION_FIELD_TYPES.has(fieldType) || ASSOCIATION_FIELD_INTERFACES.has(fieldInterface);
}
function resolveFieldFromCollection(collection, fieldPath) {
  var _a, _b, _c;
  if (!collection || !fieldPath) {
    return null;
  }
  if (typeof (collection == null ? void 0 : collection.getFieldByPath) === "function") {
    const direct = collection.getFieldByPath(fieldPath);
    if (direct) {
      return direct;
    }
  }
  const [head, ...rest] = String(fieldPath || "").split(".").filter(Boolean);
  const field = ((_a = collection == null ? void 0 : collection.getField) == null ? void 0 : _a.call(collection, head)) || ((_c = (_b = collection == null ? void 0 : collection.fields) == null ? void 0 : _b.get) == null ? void 0 : _c.call(_b, head));
  if (!field || rest.length === 0) {
    return field || null;
  }
  const targetCollection = resolveFieldTargetCollection(field, collection == null ? void 0 : collection.dataSourceKey, () => null);
  if (!targetCollection) {
    return null;
  }
  return resolveFieldFromCollection(targetCollection, rest.join("."));
}
function resolveFieldTargetCollection(field, dataSourceKey, getCollection) {
  return (typeof (field == null ? void 0 : field.targetCollection) === "function" ? field.targetCollection() : field == null ? void 0 : field.targetCollection) || (getFieldTarget(field) ? getCollection(dataSourceKey || "main", getFieldTarget(field)) : null);
}
function buildCatalogCollectionCycleKey(collection, dataSourceKey) {
  var _a;
  if (!collection) {
    return void 0;
  }
  return `${dataSourceKey || (collection == null ? void 0 : collection.dataSourceKey) || "main"}:${(collection == null ? void 0 : collection.name) || ((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.name) || (collection == null ? void 0 : collection.title) || "unknown"}`;
}
function dedupeVisibleFieldCandidates(candidates) {
  const seen = /* @__PURE__ */ new Set();
  return candidates.filter((candidate) => {
    const dedupeKey = [
      normalizeFieldPath(candidate.fieldPath, candidate.associationPathName),
      candidate.explicitWrapperUse || "",
      candidate.explicitFieldUse || ""
    ].join("::");
    if (seen.has(dedupeKey)) {
      return false;
    }
    seen.add(dedupeKey);
    return true;
  });
}
function getAssociationFilterTargetKey(field, targetCollection) {
  var _a;
  const resolvedTargetCollection = targetCollection || resolveFieldTargetCollection(field, "", () => null);
  const filterTargetKey = (resolvedTargetCollection == null ? void 0 : resolvedTargetCollection.filterTargetKey) || ((_a = resolvedTargetCollection == null ? void 0 : resolvedTargetCollection.options) == null ? void 0 : _a.filterTargetKey);
  if (Array.isArray(filterTargetKey)) {
    return filterTargetKey[0] || "id";
  }
  return filterTargetKey || "id";
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  buildCatalogCollectionCycleKey,
  buildFilterFieldMeta,
  buildFlowTemplateSearchFilter,
  dedupeVisibleFieldCandidates,
  formatChartBuilderSupportedRelationSubfields,
  getAssociationFilterTargetKey,
  getChartBuilderSupportedRelationSubfields,
  getCollectionFields,
  getCollectionModelAttributes,
  getCollectionName,
  getCollectionTitle,
  getCollectionTitleFieldName,
  getFieldFilterable,
  getFieldInterface,
  getFieldName,
  getFieldTarget,
  getFieldTitle,
  getFieldType,
  getInvalidChartBuilderRelationDirectSubfieldDetails,
  getUnsupportedChartBuilderRelationSubfieldDetails,
  hasConfiguredFlowContextValue,
  inferAssociationLeafDisplayFieldUse,
  inferFieldMenuEditableFieldUse,
  inferFlowContextTypeFromField,
  isAssociationField,
  normalizeFieldPath,
  normalizeTemplatePage,
  normalizeTemplatePageSize,
  resolveAssociationNameFromField,
  resolveFieldFromCollection,
  resolveFieldTargetCollection,
  toTemplatePlainRow
});
