var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __rest = (this && this.__rest) || function (s, e) {
  var t = {};
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
    t[p] = s[p];
  if (s != null && typeof Object.getOwnPropertySymbols === "function")
    for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
      if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
        t[p[i]] = s[p[i]];
    }
  return t;
};
import { h } from '@stencil/core';
import { MapToComponentField, VegaSlimmer } from 'vega-slimmer/core';
import { VegaTableEditableFieldTypes, } from '../../interface';
import { getValueByPath } from '../../../../utils/object';
import { LogUtility } from '../../../../utils/log';
export class VegaTableCellRenderer extends VegaSlimmer {
  constructor() {
    super(...arguments);
    this.renderTableCellContent = (column, record, index) => {
      var _a, _b;
      const value = getValueByPath(record, column.prop);
      const rowKey = this.vegaTableDataSourceController.getRecordKey(record);
      const isNewRow = !this.vegaTableDataSourceController
        .getDataSource()
        .find((item) => this.vegaTableDataSourceController.getRecordKey(item) === rowKey);
      const editing = this.vegaTableEditableController.isEditing(rowKey);
      const rowForm = this.vegaTableEditableController.getRowFormRefMap().get(rowKey);
      if (editing && rowForm && column.renderFormItem) {
        return column.renderFormItem(h, column.prop ? value : rowKey, record, index, {
          rowForm,
          isNewRow,
        });
      }
      if (editing && rowForm && column.editable) {
        const formItemProps = (_a = column.formItemProps) === null || _a === void 0 ? void 0 : _a.call(column, rowForm, {
          record,
          index,
        });
        const mergedProps = Object.assign({ dataVegaForm: (formItemProps === null || formItemProps === void 0 ? void 0 : formItemProps.dataVegaForm) || column.prop, size: 'small', value: value }, (_b = column.formItemProps) === null || _b === void 0 ? void 0 : _b.call(column, rowForm, { record, index }));
        return this.generateEditComponentByType(column.formItemType, mergedProps);
      }
      if (column.render) {
        return column.render(h, column.prop ? value : rowKey, record, index);
      }
      if (typeof value === 'string' || typeof value === 'number') {
        return String(value);
      }
      else if (typeof value === 'undefined' || value === null) {
        return '';
      }
      else {
        LogUtility.error(`Column ${column.prop}'s value has a wrong type(${typeof record[column.prop]}) in table cell. Only 'VegaTableNode | string | number' can be rendered in table cell`);
      }
    };
    /**
     * Generate edit component by
     *
     * @param {VegaTableFormItemType} type - The type of the vega components
     * @param {VegaTableEditComponentProps} props - The component props
     * @returns {VegaTableNode} The node of VegaTable
     */
    this.generateEditComponentByType = (type = 'input', props) => {
      const tagName = `vega-${type}`;
      const { dataVegaForm } = props, componentProps = __rest(props, ["dataVegaForm"]);
      if (!this.isVegaTableEditableFieldType(tagName)) {
        LogUtility.error(`Type must be one of the form field types. [${VegaTableEditableFieldTypes.join(',')}]`);
        return;
      }
      return h(tagName, Object.assign(Object.assign({}, componentProps), { 'data-vega-form': dataVegaForm }));
    };
    /**
     * Verify the tagName is editable field type
     *
     * @param {string} tagName The component tag name
     * @returns {boolean} return true if the tagName is editable field in VegaTable
     */
    this.isVegaTableEditableFieldType = (tagName) => {
      return (tagName.toUpperCase().startsWith('VEGA') &&
        new RegExp(VegaTableEditableFieldTypes.join('|'), 'i').test(tagName));
    };
  }
  render(renderInput, record, index) {
    const column = this.columns.find((column) => column.key === renderInput.key ||
      column.prop === renderInput.key ||
      column.label === renderInput.key);
    if (column) {
      const rowKey = this.vegaTableDataSourceController.getRecordKey(record);
      const columnKey = `${rowKey}_${column.key || column.prop}`;
      return (h("vega-table-cell", { key: columnKey, textAlign: column.align, breakpoint: column.breakpoint, overflow: column.overflow, ref: (ref) => {
          this.vegaTableRenderInputController.addCellRenderInputMap(ref, renderInput);
        } }, this.renderTableCellContent(column, record, index)));
    }
    else {
      return (h("vega-table-cell", { key: renderInput.key, ref: (ref) => {
          this.vegaTableRenderInputController.addCellRenderInputMap(ref, renderInput);
        } }));
    }
  }
}
__decorate([
  MapToComponentField()
], VegaTableCellRenderer.prototype, "rowKey", void 0);
__decorate([
  MapToComponentField()
], VegaTableCellRenderer.prototype, "columns", void 0);
__decorate([
  MapToComponentField()
], VegaTableCellRenderer.prototype, "vegaTableDataSourceController", void 0);
__decorate([
  MapToComponentField()
], VegaTableCellRenderer.prototype, "vegaTableEditableController", void 0);
__decorate([
  MapToComponentField()
], VegaTableCellRenderer.prototype, "vegaTableRenderInputController", void 0);
