/**
 * 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 field_binding_registry_exports = {};
__export(field_binding_registry_exports, {
  MULTI_VALUE_ASSOCIATION_INTERFACES: () => import_association_interfaces2.MULTI_VALUE_ASSOCIATION_INTERFACES,
  SINGLE_VALUE_ASSOCIATION_INTERFACES: () => import_association_interfaces2.SINGLE_VALUE_ASSOCIATION_INTERFACES,
  getRegisteredFieldUses: () => getRegisteredFieldUses,
  resolveRegisteredFieldBinding: () => resolveRegisteredFieldBinding
});
module.exports = __toCommonJS(field_binding_registry_exports);
var import_field_semantics = require("./field-semantics");
var import_service_helpers = require("./service-helpers");
var import_association_interfaces2 = require("./association-interfaces");
const FILE_MANAGER_PLUGIN = "@nocobase/plugin-file-manager";
const ATTACHMENT_URL_PLUGIN = "@nocobase/plugin-field-attachment-url";
const CODE_PLUGIN = "@nocobase/plugin-field-code";
const FORMULA_PLUGIN = "@nocobase/plugin-field-formula";
const CHINA_REGION_PLUGIN = "@nocobase/plugin-field-china-region";
const MAP_PLUGIN = "@nocobase/plugin-map";
const MARKDOWN_VDITOR_PLUGIN = "@nocobase/plugin-field-markdown-vditor";
const SORT_PLUGIN = "@nocobase/plugin-field-sort";
function getCollectionTemplate(collection) {
  var _a;
  return (collection == null ? void 0 : collection.template) || ((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.template);
}
function isAttachmentInterface(field) {
  return String((0, import_service_helpers.getFieldInterface)(field) || "").trim() === "attachment";
}
function getFieldDataType(field) {
  var _a;
  return (field == null ? void 0 : field.dataType) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.dataType);
}
function isNumericFormulaDataType(dataType) {
  return ["integer", "bigInt", "double", "decimal", "number"].includes(String(dataType || "").trim());
}
function resolveTargetCollection(input) {
  var _a;
  if ((_a = input.field) == null ? void 0 : _a.targetCollection) {
    return input.field.targetCollection;
  }
  if (!input.getCollection || !input.dataSourceKey) {
    return null;
  }
  return (0, import_service_helpers.resolveFieldTargetCollection)(input.field, input.dataSourceKey, input.getCollection);
}
function normalizeBindingContainerUse(containerUse) {
  const normalized = String(containerUse || "").trim();
  if (normalized === "FormAssociationItemModel") {
    return "DetailsItemModel";
  }
  return normalized;
}
function resolveBindingScope(containerUse) {
  switch ((0, import_field_semantics.normalizeFieldContainerKind)(normalizeBindingContainerUse(containerUse))) {
    case "table":
    case "details":
      return "display";
    case "form":
      return "editable";
    case "filter-form":
      return "filter";
    default:
      return null;
  }
}
function isRuleAvailable(rule, enabledPackages) {
  if (!rule.ownerPlugin || !enabledPackages) {
    return true;
  }
  return enabledPackages.has(rule.ownerPlugin);
}
function selectPreferredDefaultRule(rules) {
  if (!rules.length) {
    return null;
  }
  return rules.find((rule) => typeof rule.when === "function") || rules[0];
}
const FIELD_BINDING_RULE_DEFINITIONS = [
  {
    scope: "display",
    modelClassName: "DisplayPreviewFieldModel",
    interfaces: ["attachment", "attachmentURL", "m2m", "m2o", "o2o", "o2m", "oho", "obo", "mbm"],
    ownerPlugin: FILE_MANAGER_PLUGIN,
    isDefault: true,
    when: ({ field, targetCollection }) => isAttachmentInterface(field) || !targetCollection || getCollectionTemplate(targetCollection) === "file"
  },
  {
    scope: "editable",
    modelClassName: "UploadFieldModel",
    interfaces: ["attachment", "m2m", "m2o", "o2o", "o2m", "oho", "obo", "updatedBy", "createdBy", "mbm"],
    ownerPlugin: FILE_MANAGER_PLUGIN,
    isDefault: true,
    order: 30,
    when: ({ field, targetCollection }) => isAttachmentInterface(field) || !targetCollection || getCollectionTemplate(targetCollection) === "file"
  },
  {
    scope: "editable",
    modelClassName: "AttachmentURLFieldModel",
    interfaces: ["attachmentURL"],
    ownerPlugin: ATTACHMENT_URL_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayTextFieldModel",
    interfaces: ["attachmentURL"],
    ownerPlugin: ATTACHMENT_URL_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "CodeFieldModel",
    interfaces: ["code"],
    ownerPlugin: CODE_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayCodeFieldModel",
    interfaces: ["code"],
    ownerPlugin: CODE_PLUGIN,
    isDefault: true
  },
  {
    scope: "filter",
    modelClassName: "InputFieldModel",
    interfaces: ["code"],
    ownerPlugin: CODE_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "VditorFieldModel",
    interfaces: ["vditor", "markdown"],
    ownerPlugin: MARKDOWN_VDITOR_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayVditorFieldModel",
    interfaces: ["vditor", "markdown"],
    ownerPlugin: MARKDOWN_VDITOR_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "ChinaRegionFieldModel",
    interfaces: ["chinaRegion"],
    ownerPlugin: CHINA_REGION_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayChinaRegionFieldModel",
    interfaces: ["chinaRegion"],
    ownerPlugin: CHINA_REGION_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "SortFieldModel",
    interfaces: ["sort"],
    ownerPlugin: SORT_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayNumberFieldModel",
    interfaces: ["sort"],
    ownerPlugin: SORT_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "PointFieldModel",
    interfaces: ["point"],
    ownerPlugin: MAP_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "CircleFieldModel",
    interfaces: ["circle"],
    ownerPlugin: MAP_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "PolygonFieldModel",
    interfaces: ["polygon"],
    ownerPlugin: MAP_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "LineStringFieldModel",
    interfaces: ["lineString"],
    ownerPlugin: MAP_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayPointFieldModel",
    interfaces: ["point"],
    ownerPlugin: MAP_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayCircleFieldModel",
    interfaces: ["circle"],
    ownerPlugin: MAP_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayPolygonFieldModel",
    interfaces: ["polygon"],
    ownerPlugin: MAP_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayLineStringFieldModel",
    interfaces: ["lineString"],
    ownerPlugin: MAP_PLUGIN,
    isDefault: true
  },
  {
    scope: "editable",
    modelClassName: "FormulaFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    isDefault: true
  },
  {
    scope: "display",
    modelClassName: "DisplayCheckboxFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    isDefault: true,
    when: ({ field }) => getFieldDataType(field) === "boolean"
  },
  {
    scope: "display",
    modelClassName: "DisplayDateTimeFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    isDefault: true,
    when: ({ field }) => getFieldDataType(field) === "date"
  },
  {
    scope: "display",
    modelClassName: "DisplayTextFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    isDefault: true,
    when: ({ field }) => getFieldDataType(field) === "string"
  },
  {
    scope: "display",
    modelClassName: "DisplayNumberFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    isDefault: true,
    when: ({ field }) => ["double", "bigInt", "integer"].includes(String(getFieldDataType(field) || "").trim())
  },
  {
    scope: "filter",
    modelClassName: "InputFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    when: ({ field }) => {
      const dataType = String(getFieldDataType(field) || "").trim();
      return !["date", "boolean", "integer", "bigInt", "double", "decimal", "number"].includes(dataType);
    }
  },
  {
    scope: "filter",
    modelClassName: "DateTimeFilterFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    when: ({ field }) => getFieldDataType(field) === "date"
  },
  {
    scope: "filter",
    modelClassName: "CheckboxFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    when: ({ field }) => getFieldDataType(field) === "boolean"
  },
  {
    scope: "filter",
    modelClassName: "NumberFieldModel",
    interfaces: ["formula"],
    ownerPlugin: FORMULA_PLUGIN,
    when: ({ field }) => isNumericFormulaDataType(getFieldDataType(field))
  }
];
const FIELD_BINDING_RULES = FIELD_BINDING_RULE_DEFINITIONS.map((rule, index) => ({
  ...rule,
  index
}));
function getRegisteredFieldUses(scope, enabledPackages) {
  const uses = /* @__PURE__ */ new Set();
  FIELD_BINDING_RULES.forEach((rule) => {
    if (scope && rule.scope !== scope) {
      return;
    }
    if (!isRuleAvailable(rule, enabledPackages)) {
      return;
    }
    uses.add(rule.modelClassName);
  });
  return uses;
}
function resolveRegisteredFieldBinding(input) {
  const scope = resolveBindingScope(input.containerUse);
  const fieldInterface = String((0, import_service_helpers.getFieldInterface)(input.field) || "").trim();
  if (!scope || !fieldInterface) {
    return null;
  }
  const targetCollection = resolveTargetCollection(input);
  const candidates = FIELD_BINDING_RULES.filter((rule) => {
    if (rule.scope !== scope) {
      return false;
    }
    if (!rule.interfaces.includes(fieldInterface)) {
      return false;
    }
    if (!isRuleAvailable(rule, input.enabledPackages)) {
      return false;
    }
    if (!rule.when) {
      return true;
    }
    return rule.when({
      ...input,
      targetCollection
    });
  }).sort((a, b) => {
    const orderDelta = Number(a.order || 0) - Number(b.order || 0);
    return orderDelta || a.index - b.index;
  });
  const defaultRule = selectPreferredDefaultRule(candidates.filter((rule) => rule.isDefault));
  if (defaultRule) {
    return {
      modelClassName: defaultRule.modelClassName,
      ownerPlugin: defaultRule.ownerPlugin,
      isDefault: true
    };
  }
  if (input.useStrictOnly) {
    return null;
  }
  const fallbackRule = candidates[0];
  if (!fallbackRule) {
    return null;
  }
  return {
    modelClassName: fallbackRule.modelClassName,
    ownerPlugin: fallbackRule.ownerPlugin,
    isDefault: !!fallbackRule.isDefault
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  MULTI_VALUE_ASSOCIATION_INTERFACES,
  SINGLE_VALUE_ASSOCIATION_INTERFACES,
  getRegisteredFieldUses,
  resolveRegisteredFieldBinding
});
