"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
var _extends4 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _upload = _interopRequireDefault(require("@alifd/next/lib/upload"));
var _numberPicker = _interopRequireDefault(require("@alifd/next/lib/number-picker"));
var _datePicker = _interopRequireDefault(require("@alifd/next/lib/date-picker"));
var _checkbox = _interopRequireDefault(require("@alifd/next/lib/checkbox"));
var _radio = _interopRequireDefault(require("@alifd/next/lib/radio"));
var _button = _interopRequireDefault(require("@alifd/next/lib/button"));
var _select = _interopRequireDefault(require("@alifd/next/lib/select"));
var _input = _interopRequireDefault(require("@alifd/next/lib/input"));
var _responsiveGrid = _interopRequireDefault(require("@alifd/next/lib/responsive-grid"));
var _form = _interopRequireDefault(require("@alifd/next/lib/form"));
var _react = _interopRequireWildcard(require("react"));
require("./index.scss");
var _excluded = ["format", "showTime"],
  _excluded2 = ["columns", "spacing", "emptyContent", "formItems", "initialValues", "computedFields", "fieldLinkage", "submitMapping", "fullWidth", "showSubmit", "submitText", "submitValidate", "submitDataSource", "submitButtonProps", "showReset", "resetText", "resetButtonProps", "operations", "operationAlign", "onSubmit", "onSubmitFailed", "onChange", "onReset", "children", "labelAlign", "labelCol", "size"];
/**
 * CustomForm v0.5
 * 阶段一新增能力：
 *   - onChange(field, value, allValues)  统一字段变化事件，消灭所有 onXxxChange 样板函数
 *   - initialValues                       属性面板直接配置字段初始值，无需在页面 state 手写
 *   - computedFields                      声明式模板字符串计算衍生字段，提交时自动合并
 * 阶段二新增能力：
 *   - DateTimePicker                      日期时间组件，格式化为 YYYY-MM-DD HH:mm
 *   - optionsBind                         下拉/单选/复选选项支持变量绑定（动态数据源）
 *   - fieldLinkage                        字段联动：选 A → 自动填 B/C（从数据源查找匹配项）
 *   - submitMapping                       提交映射：自动组装 itemList 格式，消灭手写 onSubmitClick
 * 阶段三新增能力：
 *   - labelAlign                          全局标签位置（top/left/inset），对齐 Fusion Form 标准
 *   - fullWidth（全局）                    全局控制所有表单项组件是否 100% 宽，可被单项覆盖
 *   - isPreview                           全局预览/只读态（依赖 Fusion Form isPreview 广播）
 *   - labelCol / wrapperCol               via otherProps 透传，labelAlign=left 时配合使用
 *   - onReset                             点击重置按钮后触发的回调事件
 */
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
// ─── 调试日志工具（阶段一）────────────────────────────────────────────────────
var DEBUG_PREFIX = '[CustomForm v0.4]';
var cfLog = function cfLog(tag) {
  var _console;
  // 生产环境可通过 window.__CUSTOM_FORM_DEBUG__ = false 关闭
  if (typeof window !== 'undefined' && window.__CUSTOM_FORM_DEBUG__ === false) return;
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    args[_key - 1] = arguments[_key];
  }
  (_console = console).log.apply(_console, [DEBUG_PREFIX + " [" + tag + "]"].concat(args));
};
var cfWarn = function cfWarn(tag) {
  var _console2;
  for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
    args[_key2 - 1] = arguments[_key2];
  }
  (_console2 = console).warn.apply(_console2, [DEBUG_PREFIX + " [" + tag + "]"].concat(args));
};
// ─────────────────────────────────────────────────────────────────────────────

var NextFormAny = _form["default"];
var ResponsiveGridAny = _responsiveGrid["default"];
var ResponsiveGridCell = _responsiveGrid["default"].Cell;
var FormItemAny = _form["default"].Item;
var InputAny = _input["default"];
var TextAreaAny = _input["default"].TextArea;
var SelectAny = _select["default"];
var ButtonAny = _button["default"];
var RadioGroupAny = _radio["default"].Group;
var CheckboxGroupAny = _checkbox["default"].Group;
var DatePickerAny = _datePicker["default"];
var NumberPickerAny = _numberPicker["default"];
var UploadAny = _upload["default"];

/**
 * computedFields：计算字段映射表
 * key   = 要写入 values 的字段名
 * value = 模板字符串，用 {fieldName} 引用其他字段值
 * 示例：{ "order_desc": "{package_name},{package_price},日期：{banquet_date}" }
 */

/**
 * 字段联动规则（阶段二 + 阶段四 UX 简化）
 *
 * 【简单格式（推荐）】— 属性面板 ArraySetter 可视化编辑，每条规则对应一行：
 *   { watchField, matchValue?, fillField, fillValue }
 *   watchField  = 监听哪个字段变化
 *   matchValue  = 匹配值（留空 = 任何变化都触发）
 *   fillField   = 要回填的目标字段名
 *   fillValue   = 回填的具体值
 *
 * 【高级格式（兼容旧配置）】— 支持动态数据源查找 + staticRules 嵌套格式：
 *   { watchField, dataSource?, matchKey?, fillFields?, staticRules? }
 */

/** 提交映射 item（阶段二） */

/** rename 模式：单条字段重命名规则 */

/**
 * 操作按钮配置项（阶段四新增）
 * 表单底部可配置多个按钮，每个按钮均可独立设置操作类型与数据源。
 */

/**
 * 提交参数配置（阶段五扩展）
 *
 * 三种工作模式（mode）：
 * - 'passthrough'：直接将 finalValues 作为请求参数，无需任何配置（字段名与 API 参数名相同时使用）。
 * - 'rename'：按 fieldRenameMap 规则重命名指定字段，未列出的字段保持原名透传；
 *             适合字段名与 API 参数名不一致的标准 REST 接口。
 * - 'itemList'：将字段转换为动态表单格式 [{columnName, columnValue}]，
 *              适合 /source/api/dynamicFormTableRecord/ 等动态表单接口。
 *
 * 向后兼容：未设置 mode 时，若 items 不为空则自动识别为 'itemList' 模式，否则等同于 'passthrough'。
 */

// ─── 工具：模板字符串渲染 ─────────────────────────────────────────────────────
/**
 * 将 "{fieldA},{fieldB}" 中的占位符替换为 values 对应的真实值
 */
var renderTemplate = function renderTemplate(template, values) {
  return template.replace(/\{(\w+)\}/g, function (_, key) {
    var val = values[key];
    return val !== undefined && val !== null ? String(val) : '';
  });
};

/**
 * 将 initialValues 从数组格式标准化为对象格式（向后兼容）。
 * 数组格式由低代码设计器属性面板存储：[{field, valueType, value}, ...]
 * 对象格式为运行时使用：{ fieldName: value, ... }
 */
var normalizeInitialValues = function normalizeInitialValues(raw) {
  if (!raw) return {};
  if (Array.isArray(raw)) {
    return raw.reduce(function (acc, item) {
      if (item && item.field) {
        acc[item.field] = item.value !== undefined ? item.value : '';
      }
      return acc;
    }, {});
  }
  return raw;
};

/**
 * 将 computedFields 从数组格式标准化为对象格式（向后兼容）。
 * 数组格式：[{targetField, template}, ...]
 * 对象格式：{ targetField: template, ... }
 */
var normalizeComputedFields = function normalizeComputedFields(raw) {
  if (!raw) return {};
  if (Array.isArray(raw)) {
    return raw.reduce(function (acc, item) {
      if (item && item.targetField) {
        acc[item.targetField] = item.template || '';
      }
      return acc;
    }, {});
  }
  return raw;
};

/**
 * 将 computedFields 的所有模板计算后合并进 values，返回新对象（不修改原值）
 */
var applyComputedFields = function applyComputedFields(values, computedFields) {
  if (!computedFields || Object.keys(computedFields).length === 0) return values;
  var result = (0, _extends4["default"])({}, values);
  Object.keys(computedFields).forEach(function (key) {
    result[key] = renderTemplate(computedFields[key], result);
  });
  cfLog('computedFields', '计算字段结果', result);
  return result;
};
// ─────────────────────────────────────────────────────────────────────────────

var runSubmitDataSource = function runSubmitDataSource(submitDataSource, values, errors, field) {
  if (!submitDataSource) return;
  if (typeof submitDataSource === 'function') {
    submitDataSource(values, errors, field);
    return;
  }
  // lowcode-engine 数据源对象（this.dataSourceMap.xxx）使用 .load(params) 触发请求。
  // params 会与数据源静态 options.params 合并覆盖；
  // 若 submitMapping 已配置，values 中包含 itemList，可直接覆盖接口默认参数。
  if (typeof (submitDataSource === null || submitDataSource === void 0 ? void 0 : submitDataSource.load) === 'function') {
    submitDataSource.load(values);
    return;
  }
  if (typeof (submitDataSource === null || submitDataSource === void 0 ? void 0 : submitDataSource.run) === 'function') {
    submitDataSource.run(values, errors, field);
    return;
  }
  if (typeof (submitDataSource === null || submitDataSource === void 0 ? void 0 : submitDataSource.execute) === 'function') {
    submitDataSource.execute(values, errors, field);
    return;
  }
  if (typeof (submitDataSource === null || submitDataSource === void 0 ? void 0 : submitDataSource.request) === 'function') {
    submitDataSource.request(values, errors, field);
    return;
  }
  if (typeof (submitDataSource === null || submitDataSource === void 0 ? void 0 : submitDataSource.submit) === 'function') {
    submitDataSource.submit(values, errors, field);
  }
};
var renderFormItemComponent = function renderFormItemComponent(item) {
  var _item$optionsBind;
  var componentProps = item.componentProps || {};
  // optionsBind（动态绑定）优先级 > componentProps.dataSource > options（静态）
  var rawDataSource = (_item$optionsBind = item.optionsBind) !== null && _item$optionsBind !== void 0 && _item$optionsBind.length ? item.optionsBind : componentProps.dataSource || item.options || [];

  // 若配置了 optionsLabelKey / optionsValueKey，将原始数据字段映射到 label / value 字段
  // 这使得 API 返回的任意格式（如 {package_name, id, package_price}）均可直接用作选项数据源
  var labelKey = item.optionsLabelKey;
  var valueKey = item.optionsValueKey;
  var dataSource = (labelKey || valueKey) && Array.isArray(rawDataSource) ? rawDataSource.map(function (opt) {
    var _opt$labelKey, _opt$valueKey;
    return (0, _extends4["default"])({}, opt, labelKey ? {
      label: (_opt$labelKey = opt[labelKey]) !== null && _opt$labelKey !== void 0 ? _opt$labelKey : opt.label
    } : {}, valueKey ? {
      value: (_opt$valueKey = opt[valueKey]) !== null && _opt$valueKey !== void 0 ? _opt$valueKey : opt.value
    } : {});
  }) : rawDataSource;
  switch (item.componentType) {
    case 'TextArea':
      return /*#__PURE__*/_react["default"].createElement(TextAreaAny, componentProps);
    case 'Select':
      // dataSource 放在末尾以确保 optionsBind 优先级高于 componentProps.dataSource
      return /*#__PURE__*/_react["default"].createElement(SelectAny, (0, _extends4["default"])({}, componentProps, {
        dataSource: dataSource
      }));
    case 'RadioGroup':
      return /*#__PURE__*/_react["default"].createElement(RadioGroupAny, (0, _extends4["default"])({}, componentProps, {
        dataSource: dataSource
      }));
    case 'CheckboxGroup':
      return /*#__PURE__*/_react["default"].createElement(CheckboxGroupAny, (0, _extends4["default"])({}, componentProps, {
        dataSource: dataSource
      }));
    case 'NumberPicker':
      return /*#__PURE__*/_react["default"].createElement(NumberPickerAny, componentProps);
    case 'DatePicker':
      return /*#__PURE__*/_react["default"].createElement(DatePickerAny, (0, _extends4["default"])({
        format: "YYYY-MM-DD"
      }, componentProps));
    case 'DateTimePicker':
      {
        // 将 format / showTime 从 componentProps 中单独析构，防止 spread 覆盖我们的计算值
        var cpFormat = componentProps.format,
          _ignoredShowTime = componentProps.showTime,
          restCp = (0, _objectWithoutPropertiesLoose2["default"])(componentProps, _excluded);
        var dtFmt = cpFormat || 'YYYY-MM-DD HH:mm:ss';
        // 提取日期部分（空格前）和时间部分（空格后）
        // @alifd/next DatePicker 会将 format（日期）与 showTime.format（时间）拼接显示
        // 若把含时间的完整格式传给 format，再传 showTime.format，会导致时间重复显示
        var spaceIdx = dtFmt.indexOf(' ');
        var dateFmt = spaceIdx !== -1 ? dtFmt.slice(0, spaceIdx) : dtFmt;
        var timeFmt = spaceIdx !== -1 ? dtFmt.slice(spaceIdx + 1) : 'HH:mm:ss';
        return /*#__PURE__*/_react["default"].createElement(DatePickerAny, (0, _extends4["default"])({}, restCp, {
          format: dateFmt,
          showTime: {
            format: timeFmt
          }
        }));
      }
    case 'Upload':
      return /*#__PURE__*/_react["default"].createElement(UploadAny, componentProps);
    case 'Input':
    default:
      return /*#__PURE__*/_react["default"].createElement(InputAny, componentProps);
  }
};
var CustomForm = function CustomForm(_ref) {
  var _ref$columns = _ref.columns,
    columns = _ref$columns === void 0 ? 1 : _ref$columns,
    _ref$spacing = _ref.spacing,
    spacing = _ref$spacing === void 0 ? [0, 16] : _ref$spacing,
    _ref$emptyContent = _ref.emptyContent,
    emptyContent = _ref$emptyContent === void 0 ? '添加表单项' : _ref$emptyContent,
    _ref$formItems = _ref.formItems,
    formItems = _ref$formItems === void 0 ? [] : _ref$formItems,
    initialValues = _ref.initialValues,
    computedFields = _ref.computedFields,
    fieldLinkage = _ref.fieldLinkage,
    submitMapping = _ref.submitMapping,
    globalFullWidth = _ref.fullWidth,
    _ref$showSubmit = _ref.showSubmit,
    showSubmit = _ref$showSubmit === void 0 ? true : _ref$showSubmit,
    _ref$submitText = _ref.submitText,
    submitText = _ref$submitText === void 0 ? '提交' : _ref$submitText,
    _ref$submitValidate = _ref.submitValidate,
    submitValidate = _ref$submitValidate === void 0 ? true : _ref$submitValidate,
    submitDataSource = _ref.submitDataSource,
    submitButtonProps = _ref.submitButtonProps,
    _ref$showReset = _ref.showReset,
    showReset = _ref$showReset === void 0 ? false : _ref$showReset,
    _ref$resetText = _ref.resetText,
    resetText = _ref$resetText === void 0 ? '重置' : _ref$resetText,
    resetButtonProps = _ref.resetButtonProps,
    operations = _ref.operations,
    _ref$operationAlign = _ref.operationAlign,
    operationAlign = _ref$operationAlign === void 0 ? 'center' : _ref$operationAlign,
    onSubmit = _ref.onSubmit,
    onSubmitFailed = _ref.onSubmitFailed,
    onChange = _ref.onChange,
    onReset = _ref.onReset,
    children = _ref.children,
    labelAlign = _ref.labelAlign,
    labelCol = _ref.labelCol,
    globalSize = _ref.size,
    otherProps = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded2);
  // ─── 直接传递列数，通过 device="desktop" 锁定成桌面模式，防止 ResponsiveGrid 根据视口自动缩列
  // ResponsiveGrid columns 只接受 number/string，不接受 breakpoint 对象
  var fixedColumns = columns;

  // ─── 兼容旧版 4-value spacing → 标准化为 [rowGap, colGap] ─────────────────
  var normalizedGap = (0, _react.useMemo)(function () {
    var _spacing$, _spacing$2;
    if (!Array.isArray(spacing)) return spacing;
    if (spacing.length >= 2) return [spacing[0], spacing[1]];
    return [(_spacing$ = spacing[0]) !== null && _spacing$ !== void 0 ? _spacing$ : 0, (_spacing$2 = spacing[0]) !== null && _spacing$2 !== void 0 ? _spacing$2 : 16];
  }, [spacing]);

  // ─── 标准化 initialValues / computedFields（支持设计器生成的数组格式与运行时对象格式）
  var resolvedInitialValues = (0, _react.useMemo)(function () {
    return normalizeInitialValues(initialValues);
  }, [initialValues]);
  var resolvedComputedFields = (0, _react.useMemo)(function () {
    return normalizeComputedFields(computedFields);
  }, [computedFields]);

  // ─── 用 ref 缓存所有字段的当前值，避免 onChange 闭包过期 ──────────────────
  // 初始化时直接合并 resolvedInitialValues，避免 useEffect 延迟问题
  var valuesRef = (0, _react.useRef)(resolvedInitialValues ? (0, _extends4["default"])({}, resolvedInitialValues) : {});

  // ─── 缓存最新的 formItems，避免 handleFieldChange 闭包访问过期值 ─────────
  var formItemsRef = (0, _react.useRef)(formItems);
  (0, _react.useEffect)(function () {
    formItemsRef.current = formItems;
  }, [formItems]);

  // ─── 联动回填触发器：用 state 驱动组件重渲染以更新受控字段 ───────────────
  // 注意：不预填 resolvedInitialValues，初始值通过 defaultValue（非受控）处理
  // 预填会导致所有有初始值的字段变为受控组件，用户改值后因 linkageValues 未更新而回显旧值
  var _useState = (0, _react.useState)({}),
    linkageValues = _useState[0],
    setLinkageValues = _useState[1];

  // ─── Bug Fix: initialValues 变化时同步 valuesRef（编辑模式异步加载场景）──────
  // 用 JSON.stringify 做深比较，避免父组件每次重渲染都因内联对象引用变化触发重置
  var lastInitSerialRef = (0, _react.useRef)('');
  (0, _react.useEffect)(function () {
    var serial = JSON.stringify(resolvedInitialValues);
    if (serial !== lastInitSerialRef.current) {
      lastInitSerialRef.current = serial;
      valuesRef.current = resolvedInitialValues ? (0, _extends4["default"])({}, resolvedInitialValues) : {};
      setLinkageValues({});
      cfLog('initialValues', 'initialValues 已变更，重新初始化 valuesRef', resolvedInitialValues);
    }
  }, [resolvedInitialValues]);

  // ─── 统一 onChange 处理器（阶段一 + 阶段二核心）─────────────────────────────
  var handleFieldChange = (0, _react.useCallback)(function (field, value) {
    var _extends2;
    // 1. 更新本地 values 缓存
    valuesRef.current = (0, _extends4["default"])({}, valuesRef.current, (_extends2 = {}, _extends2[field] = value, _extends2));
    cfLog('onChange', "\u5B57\u6BB5 \"" + field + "\" \u53D8\u5316", {
      value: value,
      allValues: valuesRef.current
    });

    // 2. 字段联动（阶段二）
    if (fieldLinkage && fieldLinkage.length > 0) {
      // ── 第一步：收集当前 watchField 所有规则"可能影响"到的字段（预清除范围）──────
      // 目的：当用户把 watchField 改为不匹配任何规则的值时，
      // 把上一次联动写入的字段清回初始值，而不是永久保留旧的联动值。
      var clearableFields = new Set();
      fieldLinkage.forEach(function (rule) {
        if (rule.watchField !== field) return;
        if (rule.fillField) clearableFields.add(rule.fillField);
        if (rule.fillFields) Object.keys(rule.fillFields).forEach(function (f) {
          return clearableFields.add(f);
        });
        if (rule.staticRules) {
          Object.values(rule.staticRules).forEach(function (ruleMap) {
            return Object.keys(ruleMap).forEach(function (f) {
              return clearableFields.add(f);
            });
          });
        }
      });

      // ── 第二步：按规则计算本次实际要写入的值 ────────────────────────────────────
      var fills = {};
      fieldLinkage.forEach(function (rule) {
        if (rule.watchField !== field) return;

        // 2a. 静态联动规则（高级格式）
        if (rule.staticRules) {
          var staticFill = rule.staticRules[String(value)];
          if (staticFill) {
            Object.assign(fills, staticFill);
            cfLog('linkage', "\u9759\u6001\u8054\u52A8 \"" + field + "\" = " + value + "\uFF0C\u56DE\u586B", staticFill);
          }
        }

        // 2b. 数据源动态联动（高级格式）
        if (rule.dataSource && rule.fillFields) {
          // ─── 防御：dataSource 必须是数组 ───────────────────────────────────────
          // 若属性面板 dataSource 字段未通过「变量绑定」控件正确绑定，
          // 而是直接输入了文本（如 "this.state.xxx"），则 rule.dataSource 为字符串而非数组。
          // 在非数组上调用 .find() 会抛 TypeError，该错误会在 Fusion Field 的 onChange 包装
          // 器中向上传播，阻断 _reRender（即 instance.forceUpdate()）的调用，导致：
          //   1. Form 不重新渲染 → 下拉选中值消失（Select 回显空白）
          //   2. setLinkageValues 未执行 → 联动回填字段不更新
          // 因此必须先做类型守卫，跳过非数组情况并给出明确提示。
          if (!Array.isArray(rule.dataSource)) {
            cfWarn('linkage', "\u52A8\u6001\u8054\u52A8\uFF08watchField=\"" + rule.watchField + "\"\uFF09\u7684 dataSource \u4E0D\u662F\u6570\u7EC4" + ("\uFF08\u5B9E\u9645\u7C7B\u578B\uFF1A" + typeof rule.dataSource + "\uFF0C\u503C\uFF1A" + JSON.stringify(rule.dataSource) + "\uFF09\u3002") + "\u8BF7\u5728\u5C5E\u6027\u9762\u677F\u4E2D\u901A\u8FC7\u300C\u53D8\u91CF\u7ED1\u5B9A\u300D\u63A7\u4EF6\u9009\u62E9\u6570\u636E\u6E90\u53D8\u91CF\uFF0C\u4E0D\u8981\u76F4\u63A5\u8F93\u5165\u6587\u5B57\u8DEF\u5F84\u3002");
          } else {
            var _formItemsRef$current;
            var matchKey = rule.matchKey || ((_formItemsRef$current = formItemsRef.current.find(function (i) {
              return i.field === rule.watchField;
            })) === null || _formItemsRef$current === void 0 ? void 0 : _formItemsRef$current.optionsValueKey) || 'value';
            // 同时支持严格相等和字符串化比较，兼容 id 字段类型不一致（数字 vs 字符串）的场景
            var matched = rule.dataSource.find(function (item) {
              return item[matchKey] === value || item[matchKey] !== undefined && value !== undefined && String(item[matchKey]) === String(value);
            });
            if (matched) {
              var fill = {};
              Object.entries(rule.fillFields).forEach(function (_ref2) {
                var formField = _ref2[0],
                  dsKey = _ref2[1];
                // 防止把 watchField 误填进 fillFields，否则会用 undefined 覆盖用户的选择值
                if (formField === field) {
                  cfWarn('linkage', "fillFields \u4E2D\u7684 key \"" + formField + "\" \u4E0E\u76D1\u542C\u5B57\u6BB5 watchField \u76F8\u540C\uFF0C\u5DF2\u8DF3\u8FC7\u3002" + "fillFields \u683C\u5F0F\u4E3A {\"\u76EE\u6807\u8868\u5355\u5B57\u6BB5\":\"\u6570\u636E\u6E90\u5B57\u6BB5\u540D\"}\uFF0C\u8BF7\u68C0\u67E5 key/value \u662F\u5426\u5199\u53CD\u3002");
                  return;
                }
                // 数据源字段名不存在时提示可用字段，避免静默填入 undefined
                if (!(dsKey in matched)) {
                  cfWarn('linkage', "fillFields \u4E2D\u6570\u636E\u6E90\u5B57\u6BB5\u540D \"" + dsKey + "\" \u5728\u5339\u914D\u9879\u4E2D\u4E0D\u5B58\u5728\uFF0C\u5DF2\u8DF3\u8FC7\u3002" + ("\u5339\u914D\u9879\u53EF\u7528\u5B57\u6BB5\uFF1A" + Object.keys(matched).join(', ')));
                  return;
                }
                fill[formField] = matched[dsKey];
              });
              Object.assign(fills, fill);
              cfLog('linkage', "\u52A8\u6001\u8054\u52A8 \"" + field + "\" = " + value + "\uFF0C\u56DE\u586B", fill);
            } else {
              cfWarn('linkage', "\u52A8\u6001\u8054\u52A8\uFF1A\u5728 dataSource \u4E2D\u672A\u627E\u5230 matchKey=\"" + matchKey + "\" \u7B49\u4E8E \"" + value + "\" \u7684\u8BB0\u5F55\u3002" + "\u8BF7\u786E\u8BA4 matchKey \u4E0E optionsBind \u5B58\u50A8\u503C\u5B57\u6BB5\u540D\u4E00\u81F4\uFF08\u914D\u7F6E\u4E86 optionsValueKey \u65F6\u4F1A\u81EA\u52A8\u4F7F\u7528\u8BE5\u5B57\u6BB5\u540D\uFF09\uFF0C\u4E14 dataSource \u4E0E optionsBind \u540C\u6E90\u3002");
            }
          }
        }

        // 2c. 简单联动格式（新格式，属性面板可视化编辑生成）
        if (rule.fillField !== undefined && rule.fillValue !== undefined) {
          var noConstraint = rule.matchValue === undefined || rule.matchValue === '';
          var _matched = noConstraint || String(value) === String(rule.matchValue);
          if (_matched) {
            var _cfLog;
            fills[rule.fillField] = rule.fillValue;
            cfLog('linkage', "\u7B80\u5355\u8054\u52A8 \"" + field + "\" = " + value + "\uFF0C\u56DE\u586B", (_cfLog = {}, _cfLog[rule.fillField] = rule.fillValue, _cfLog));
          }
        }
      });

      // ── 第三步：同步更新 valuesRef 和 linkageValues ──────────────────────────────
      // ① 先把 clearableFields 回退为初始值（无论本次有无匹配）
      // ② 再把 fills 叠加进来（覆盖刚刚的回退值）
      // 结果：本次有匹配 → 字段显示新的联动值；本次无匹配 → 字段回退为初始值或空
      if (clearableFields.size > 0) {
        clearableFields.forEach(function (f) {
          var initVal = resolvedInitialValues === null || resolvedInitialValues === void 0 ? void 0 : resolvedInitialValues[f];
          if (initVal !== undefined) {
            valuesRef.current[f] = initVal;
          } else {
            delete valuesRef.current[f];
          }
        });
        Object.assign(valuesRef.current, fills);
        setLinkageValues(function (prev) {
          var next = (0, _extends4["default"])({}, prev);
          // 删除"可被清除"但本次未填入的字段，使其退出受控状态
          clearableFields.forEach(function (f) {
            if (!(f in fills)) delete next[f];
          });
          return (0, _extends4["default"])({}, next, fills);
        });
      } else if (Object.keys(fills).length > 0) {
        // 保底路径：clearableFields 为空但仍有 fills（理论上不会出现）
        Object.assign(valuesRef.current, fills);
        setLinkageValues(function (prev) {
          return (0, _extends4["default"])({}, prev, fills);
        });
      }
    }

    // 3. 计算 computedFields，得到包含衍生字段的完整值
    var allValues = applyComputedFields(valuesRef.current, resolvedComputedFields);

    // 4. 触发外部 onChange 事件（低代码侧可绑定 updateVariable）
    if (onChange) {
      onChange(field, value, allValues);
    }
  }, [resolvedComputedFields, resolvedInitialValues, fieldLinkage, onChange]);

  // ─── 提交处理 ───────────────────────────────────────────────────────────────
  // ─── 对齐方式映射 ───────────────────────────────────────────────────────────
  var alignJustifyMap = {
    left: 'flex-start',
    center: 'center',
    right: 'flex-end'
  };

  // ─── 有效操作按钮列表 ────────────────────────────────────────────────────────
  // operations prop 存在（哪怕是空数组）时：以 operations 为准，完全忽略旧版 showSubmit/showReset
  // operations prop 为 undefined 时：回退到旧版双按钮模式（向后兼容）
  var effectiveOperations = (0, _react.useMemo)(function () {
    if (operations !== undefined) return operations;
    var ops = [];
    if (showReset) ops.push({
      text: resetText || '重置',
      action: 'reset',
      type: 'normal'
    });
    if (showSubmit) ops.push({
      text: submitText || '提交',
      action: 'submit',
      type: 'primary',
      submitValidate: submitValidate
    });
    return ops;
  }, [operations, showSubmit, submitText, submitValidate, showReset, resetText]);
  var handleSubmit = (0, _react.useCallback)(function (values, errors, field, buttonDataSource) {
    // 合并原则：valuesRef.current 优先级最高，因为它是所有变化（用户输入 + 联动回填）的唯一可信来源。
    // Form.Submit 返回的 values 中，联动回填字段没有经过 onChange，Form 内部 store
    // 可能保留初始 undefined/""，若让 values 覆盖 valuesRef 会丢失联动写入的正确值。
    // { ...values, ...valuesRef.current }：valuesRef 覆盖 Form stale 值，确保联动回填生效。
    var mergedValues = (0, _extends4["default"])({}, values, valuesRef.current);
    // 追加 computedFields 衍生字段
    var finalValues = applyComputedFields(mergedValues, resolvedComputedFields);

    // submitMapping：按 mode 构建请求参数（阶段五）
    if (submitMapping) {
      var _submitMapping$mode, _submitMapping$items, _submitMapping$fieldR, _submitMapping$items2;
      // 向后兼容：未设置 mode 时，有 items 数组则默认 itemList，否则 passthrough
      var mode = (_submitMapping$mode = submitMapping.mode) !== null && _submitMapping$mode !== void 0 ? _submitMapping$mode : (_submitMapping$items = submitMapping.items) !== null && _submitMapping$items !== void 0 && _submitMapping$items.length ? 'itemList' : 'passthrough';
      if (mode === 'rename' && (_submitMapping$fieldR = submitMapping.fieldRenameMap) !== null && _submitMapping$fieldR !== void 0 && _submitMapping$fieldR.length) {
        // ── rename：重命名指定字段，其余字段按原名透传
        var renamed = (0, _extends4["default"])({}, finalValues);
        submitMapping.fieldRenameMap.forEach(function (_ref3) {
          var fromField = _ref3.fromField,
            toField = _ref3.toField;
          if (fromField && toField && fromField in renamed) {
            renamed[toField] = renamed[fromField];
            if (fromField !== toField) delete renamed[fromField];
          }
        });
        finalValues = renamed;
        cfLog('submitMapping', 'rename 模式字段重命名完成', finalValues);
      } else if (mode === 'itemList' && (_submitMapping$items2 = submitMapping.items) !== null && _submitMapping$items2 !== void 0 && _submitMapping$items2.length) {
        var _extends3;
        // ── itemList：转换为动态表单格式 [{columnName, columnValue}]
        var targetField = submitMapping.targetField || 'itemList';
        var itemList = submitMapping.items.map(function (mappingItem) {
          var columnValue;
          if (mappingItem.field) {
            var _finalValues$mappingI;
            columnValue = (_finalValues$mappingI = finalValues[mappingItem.field]) !== null && _finalValues$mappingI !== void 0 ? _finalValues$mappingI : '';
          } else if (mappingItem.template) {
            columnValue = renderTemplate(mappingItem.template, finalValues);
          } else {
            columnValue = '';
          }
          return {
            columnName: mappingItem.columnName,
            columnValue: columnValue
          };
        });
        finalValues = (0, _extends4["default"])({}, finalValues, (_extends3 = {}, _extends3[targetField] = itemList, _extends3));
        cfLog('submitMapping', "itemList \u6A21\u5F0F\u5DF2\u751F\u6210 " + targetField, itemList);
      }
      // passthrough: finalValues 直接作为请求参数，无需处理
    }
    cfLog('submit', '提交触发', {
      rawValues: values,
      errors: errors,
      finalValues: finalValues
    });
    if (errors && Object.keys(errors).length) {
      cfWarn('submit', '校验失败', errors);
      if (onSubmitFailed) {
        onSubmitFailed(finalValues, errors, field);
      }
      return;
    }
    cfLog('submit', '校验通过，准备提交', finalValues);
    if (onSubmit) {
      onSubmit(finalValues, errors, field);
    }
    // buttonDataSource：单个按钮绑定的数据源（优先）；未绑定时回退到组件级 submitDataSource
    var effectiveDS = buttonDataSource !== null && buttonDataSource !== void 0 ? buttonDataSource : submitDataSource;
    runSubmitDataSource(effectiveDS, finalValues, errors, field);
  }, [resolvedComputedFields, submitMapping, onSubmit, onSubmitFailed, submitDataSource]);

  // ─── 重置处理：同时清除 linkageValues 和 valuesRef ────────────────────────────
  var handleReset = (0, _react.useCallback)(function () {
    setLinkageValues({});
    valuesRef.current = resolvedInitialValues ? (0, _extends4["default"])({}, resolvedInitialValues) : {};
    cfLog('reset', '表单已重置，linkageValues 和 valuesRef 已恢复初始状态');
    onReset === null || onReset === void 0 ? void 0 : onReset();
  }, [resolvedInitialValues, onReset]);

  // ─── 渲染表单项，绑定统一 onChange ──────────────────────────────────────────
  var formItemNodes = formItems.map(function (item, index) {
    var _linkageValues$item$f, _item$componentProps;
    var colSpan = Math.min(columns, Math.max(1, item.columnSpan || 1));

    // 初始值优先级：item.initialValue > linkageValues[field]（含联动回填）> initialValues[field]
    var fieldInitialValue = item.initialValue !== undefined ? item.initialValue : (_linkageValues$item$f = linkageValues[item.field]) !== null && _linkageValues$item$f !== void 0 ? _linkageValues$item$f : resolvedInitialValues === null || resolvedInitialValues === void 0 ? void 0 : resolvedInitialValues[item.field];

    // 包装组件的 onChange，注入 field 信息
    // fullWidth 优先级：item.fullWidth（单项）> globalFullWidth（全局）> undefined（不限制）
    var effectiveFullWidth = item.fullWidth !== undefined ? item.fullWidth : globalFullWidth;
    // 有效尺寸：单项 > 全局 > undefined（继承 Form 默认）
    var effectiveSize = item.size || globalSize;
    var componentPropsWithChange = (0, _extends4["default"])({}, item.placeholder ? {
      placeholder: item.placeholder
    } : {}, effectiveSize ? {
      size: effectiveSize
    } : {}, effectiveFullWidth !== undefined ? {
      style: (0, _extends4["default"])({
        width: effectiveFullWidth ? '100%' : undefined
      }, ((_item$componentProps = item.componentProps) === null || _item$componentProps === void 0 ? void 0 : _item$componentProps.style) || {})
    } : {}, item.componentProps || {}, {
      onChange: function onChange(value) {
        var _item$componentProps2;
        if (typeof ((_item$componentProps2 = item.componentProps) === null || _item$componentProps2 === void 0 ? void 0 : _item$componentProps2.onChange) === 'function') {
          item.componentProps.onChange(value);
        }
        // DatePicker / DateTimePicker 的 onChange 返回 Moment 对象，需格式化为字符串后再存储
        var storedValue = value;
        if (['DatePicker', 'DateTimePicker'].includes(item.componentType) && value && typeof value.format === 'function') {
          var _item$componentProps3;
          var fmt = ((_item$componentProps3 = item.componentProps) === null || _item$componentProps3 === void 0 ? void 0 : _item$componentProps3.format) || (item.componentType === 'DateTimePicker' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD');
          storedValue = value.format(fmt);
        }
        handleFieldChange(item.field, storedValue);
      }
    });

    // 联动回填时，通过 value（受控）覆盖字段值；否则只用 defaultValue
    var isLinkageControlled = linkageValues[item.field] !== undefined && item.initialValue === undefined;
    if (isLinkageControlled) {
      componentPropsWithChange.value = linkageValues[item.field];
    } else if (fieldInitialValue !== undefined && componentPropsWithChange.value === undefined) {
      componentPropsWithChange.defaultValue = fieldInitialValue;
      cfLog('renderItem', "\u5B57\u6BB5 \"" + item.field + "\" \u6CE8\u5165\u521D\u59CB\u503C", fieldInitialValue);
    }
    if (!item.field) {
      cfWarn('renderItem', "\u7B2C " + (index + 1) + " \u4E2A\u8868\u5355\u9879\u7F3A\u5C11 field \u5B57\u6BB5\uFF0ConChange \u5C06\u65E0\u6CD5\u7ED1\u5B9A");
    }

    // 合并 Form.Item 属性：通用属性 < 快捷字段 < formItemProps（最高优先级）
    // labelAlign / labelCol 显式传入，确保设计器中不依赖 Form context 也能生效
    var mergedFormItemProps = (0, _extends4["default"])({}, labelAlign ? {
      labelAlign: labelAlign
    } : {}, labelCol ? {
      labelCol: labelCol
    } : {}, effectiveSize ? {
      size: effectiveSize
    } : {}, item.help ? {
      help: item.help
    } : {}, item.extra ? {
      extra: item.extra
    } : {}, item.formItemProps || {});
    return /*#__PURE__*/_react["default"].createElement(ResponsiveGridCell, {
      colSpan: colSpan,
      key: (item.field || index) + "-form-item"
    }, /*#__PURE__*/_react["default"].createElement(FormItemAny, (0, _extends4["default"])({
      label: item.label,
      name: item.field,
      required: item.required
    }, mergedFormItemProps), renderFormItemComponent((0, _extends4["default"])({}, item, {
      componentProps: componentPropsWithChange
    }))));
  });
  var childrenNodes = _react["default"].Children.toArray(children).map(function (child, index) {
    if (/*#__PURE__*/_react["default"].isValidElement(child) && child.type === ResponsiveGridCell) {
      return child;
    }
    return /*#__PURE__*/_react["default"].createElement(ResponsiveGridCell, {
      colSpan: 1,
      key: "custom-form-child-" + index
    }, child);
  });
  var hasContent = formItemNodes.length > 0 || childrenNodes.length > 0;

  // initialValues 通过 defaultValue 传入 Form（非受控初始化），避免覆盖联动回填的受控值
  // 注意：必须使用 resolvedInitialValues（已标准化为对象格式），而非原始 initialValues
  // 原始值在设计器中为数组格式 [{field, valueType, value}]，直接传给 NextForm.defaultValue 无效
  var formInitialProps = {};
  if (resolvedInitialValues && Object.keys(resolvedInitialValues).length > 0) {
    formInitialProps.defaultValue = resolvedInitialValues;
    cfLog('render', '表单携带 initialValues 渲染', resolvedInitialValues);
  }
  return /*#__PURE__*/_react["default"].createElement(NextFormAny, (0, _extends4["default"])({
    className: "custom-form"
  }, labelAlign ? {
    labelAlign: labelAlign
  } : {}, labelCol ? {
    labelCol: labelCol
  } : {}, globalSize ? {
    size: globalSize
  } : {}, formInitialProps, otherProps), hasContent ? /*#__PURE__*/_react["default"].createElement(ResponsiveGridAny, {
    className: "custom-form__grid",
    device: "desktop",
    gap: normalizedGap,
    columns: fixedColumns
  }, formItemNodes, childrenNodes) : /*#__PURE__*/_react["default"].createElement("div", {
    className: "custom-form__empty"
  }, emptyContent), effectiveOperations.length > 0 ? /*#__PURE__*/_react["default"].createElement("div", {
    className: "custom-form__actions",
    style: {
      justifyContent: alignJustifyMap[operationAlign] || 'center'
    }
  }, effectiveOperations.map(function (op, opIndex) {
    // ── 重置按钮 ─────────────────────────────────────────────────────
    if (op.action === 'reset') {
      return /*#__PURE__*/_react["default"].createElement(NextFormAny.Reset, (0, _extends4["default"])({
        key: opIndex,
        type: op.type || 'normal',
        onClick: handleReset
      }, op.buttonProps || {}), op.text);
    }
    // ── 提交按钮 ─────────────────────────────────────────────────────
    if (op.action === 'submit') {
      // 每个提交按钮独立决定是否校验：per-button > 全局 submitValidate
      var btnValidate = op.submitValidate !== undefined ? op.submitValidate : submitValidate;
      return /*#__PURE__*/_react["default"].createElement(NextFormAny.Submit, (0, _extends4["default"])({
        key: opIndex,
        type: op.type || 'primary',
        validate: btnValidate,
        onClick: function onClick(values, errors, field) {
          return handleSubmit(values, errors, field, op.dataSource);
        }
      }, op.buttonProps || {}), op.text);
    }
    // ── 自定义按钮 ───────────────────────────────────────────────────
    return /*#__PURE__*/_react["default"].createElement(ButtonAny, (0, _extends4["default"])({
      key: opIndex,
      type: op.type || 'normal',
      onClick: op.onClick
    }, op.buttonProps || {}), op.text);
  })) : null);
};
CustomForm.displayName = 'CustomForm';
var _default = exports["default"] = CustomForm;