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 { Action, ApplicationContext, UserInterface } from "@sankhyalabs/core";
import { focusOnFieldSerch, FormLayout, SEARCH_FIELD_FULL_WIDTH } from '@sankhyalabs/ezui/dist/collection/utils';
import { DataBinder } from "@sankhyalabs/ezui/dist/collection/utils/form";
import { h, Host } from "@stencil/core";
import { getPKs } from "../../../snk-image-input/utils/ImageUtils";
export class SnkDynaformFormView {
  constructor() {
    this._customEditors = new Map();
    this._fieldProps = new Map();
    this.dataUnitObserver = async (action) => {
      var _a;
      if (action.type === Action.RECORDS_COPIED) {
        const sourcePK = this.buildSourceRecordPK(action);
        (_a = this.getImageField()) === null || _a === void 0 ? void 0 : _a.forEach(async (field) => {
          var _a;
          (_a = this.dataUnit) === null || _a === void 0 ? void 0 : _a.setFieldValue(field.name, JSON.stringify(sourcePK));
        });
      }
    };
    this.customUiBuilders = new Map([
      [UserInterface.IMAGE, (_a) => {
          var { name } = _a, props = __rest(_a, ["name"]);
          return h("snk-image-input", Object.assign({ dataUnit: this.dataUnit, maxSize: Infinity, fieldName: name, entityName: this.entityPath }, props));
        }
      ]
    ]);
    this._singleColumn = false;
    this._currentFormLayout = undefined;
    this.fieldSearch = undefined;
    this.label = undefined;
    this.name = undefined;
    this.fields = undefined;
    this.formMetadata = undefined;
    this.dataUnit = undefined;
    this.recordsValidator = undefined;
    this.fieldToFocus = undefined;
    this.customEditors = undefined;
    this.fieldsProps = undefined;
    this.entityPath = undefined;
  }
  async showUp() {
    var _a, _b;
    if (this._formView) {
      (_b = (_a = this._formView).showUp) === null || _b === void 0 ? void 0 : _b.call(_a);
    }
  }
  /**
   * Registra um editor customizado para campos da grade e formulário
   */
  async addCustomEditor(fieldName, customEditor, detailContext) {
    var _a, _b;
    if (this._formView) {
      (_b = (_a = this._formView).addCustomEditor) === null || _b === void 0 ? void 0 : _b.call(_a, fieldName, customEditor, detailContext);
      return;
    }
    const newCustomEditors = new Map(this._customEditors);
    newCustomEditors.set(fieldName, { customEditor, detailContext: detailContext !== null && detailContext !== void 0 ? detailContext : "" });
    this._customEditors = newCustomEditors;
  }
  /**
   * Altera/adiciona uma propriedade nos metadados do campo.
   */
  async setFieldProp(fieldName, propName, value) {
    const props = this._fieldProps.get(fieldName) || [];
    this._fieldProps.set(fieldName, [...props, { propName, value }]);
  }
  /**
   * Exibe a busca de campos ancorada ao container de cabeçalho do snk-dynaform-form-view.
   */
  async showSearchField() {
    if (!this._headerContainer || !this._ezPopoverFieldColumn)
      return;
    const container = this._headerContainer.getBoundingClientRect();
    if (this.fieldSearch) {
      await focusOnFieldSerch(this.fieldSearch);
      this._ezPopoverFieldColumn.showUnder(this._headerContainer, { horizontalGap: container.width - (SEARCH_FIELD_FULL_WIDTH), verticalGap: container.height * -1 });
    }
  }
  observePropsCustomEditor(newValue) {
    for (const fieldName in newValue) {
      this.addCustomEditor(fieldName, newValue[fieldName]);
    }
  }
  async observeFieldsProps(newValue) {
    for (const field in newValue) {
      const fieldProps = newValue[field];
      const propNames = Object.keys(fieldProps);
      for (const propName of propNames) {
        await this.setFieldProp(field, propName, fieldProps[propName]);
      }
    }
  }
  async observeDataUnit(newValue, oldValue) {
    if (newValue !== oldValue && newValue) {
      newValue.subscribe(this.dataUnitObserver);
    }
  }
  bindFields(fields) {
    var _a;
    if (this._dataBinder == undefined && this.dataUnit != undefined) {
      this._dataBinder = new DataBinder(this.dataUnit);
    }
    if (this._dataBinder && this.dataUnit && this.formMetadata) {
      this._dataBinder.bind(fields, (_a = this.dataUnit) === null || _a === void 0 ? void 0 : _a.dataUnitId, this.formMetadata, this.recordsValidator);
    }
  }
  disconnectedCallback() {
    if (this._dataBinder != undefined) {
      this._dataBinder.onDisconnectedCallback();
    }
    if (this.dataUnit) {
      this.dataUnit.unsubscribe(this.dataUnitObserver);
    }
  }
  componentDidLoad() {
    if (this.customEditors) {
      this.observePropsCustomEditor(this.customEditors);
    }
    if (this.fieldsProps) {
      this.observeFieldsProps(this.fieldsProps);
    }
    this.initLayoutFormConfig();
  }
  async initLayoutFormConfig() {
    const _application = ApplicationContext.getContextValue("__SNK__APPLICATION__");
    const layoutFormConfig = await (_application === null || _application === void 0 ? void 0 : _application.getLayoutFormConfig());
    if (layoutFormConfig) {
      this.setSingleColumn(layoutFormConfig);
      this.registerNotifyListeners(layoutFormConfig);
    }
  }
  setSingleColumn(layoutFormConfig) {
    this._singleColumn = (layoutFormConfig === null || layoutFormConfig === void 0 ? void 0 : layoutFormConfig.config) === FormLayout.CASCADE;
  }
  registerNotifyListeners(layoutFormConfig) {
    var _a;
    if (!layoutFormConfig)
      return;
    (_a = layoutFormConfig.onConfigChange) === null || _a === void 0 ? void 0 : _a.call(layoutFormConfig, (config) => {
      this._singleColumn = (config === FormLayout.CASCADE);
    });
  }
  componentDidRender() {
    var _a;
    this.setCustomEditors();
    this.setFieldProps();
    if (!this.fieldToFocus) {
      return;
    }
    if (!((_a = this.fields) === null || _a === void 0 ? void 0 : _a.some(item => item.name === this.fieldToFocus))) {
      return;
    }
    requestAnimationFrame(() => {
      var _a, _b;
      (_a = this._dataBinder) === null || _a === void 0 ? void 0 : _a.setFocus(this.fieldToFocus);
      (_b = this.snkRequestClearFieldToFocus) === null || _b === void 0 ? void 0 : _b.emit();
    });
  }
  setCustomEditors() {
    var _a, _b;
    if (!this._formView) {
      return;
    }
    for (const [fieldName, customEditorProps] of this._customEditors) {
      (_b = (_a = this._formView).addCustomEditor) === null || _b === void 0 ? void 0 : _b.call(_a, fieldName, customEditorProps.customEditor, customEditorProps.detailContext);
      this._customEditors.delete(fieldName);
    }
  }
  setFieldProps() {
    if (!this._formView) {
      return;
    }
    for (const [fieldName, propsToChange] of this._fieldProps) {
      propsToChange.forEach(prop => {
        var _a, _b;
        (_b = (_a = this._formView).setFieldProp) === null || _b === void 0 ? void 0 : _b.call(_a, fieldName, prop.propName, prop.value);
        this._fieldProps.delete(fieldName);
      });
    }
  }
  buildSourceRecordPK(action) {
    var _a, _b, _c;
    const currentRecord = ((_a = action.payload) === null || _a === void 0 ? void 0 : _a[0]) || {};
    const sourceBase64 = currentRecord["__record__source__id__"];
    const sourceRecord = JSON.parse(atob(sourceBase64 || ''));
    delete sourceRecord["__DATA_UNIT_NAME__"];
    if (!this.dataUnit) {
      return {};
    }
    const pks = (_b = getPKs(this.dataUnit)) !== null && _b !== void 0 ? _b : {};
    const pkFields = Object.keys(pks);
    const filteredSourceRecord = {};
    for (const pkField of pkFields) {
      filteredSourceRecord[pkField] = (_c = sourceRecord[pkField]) === null || _c === void 0 ? void 0 : _c.value;
    }
    return filteredSourceRecord;
  }
  getImageField() {
    var _a;
    return (_a = this.dataUnit) === null || _a === void 0 ? void 0 : _a.metadata.fields.filter(field => field.userInterface === UserInterface.IMAGE);
  }
  render() {
    return (h(Host, null, h("slot", null), h("ez-form-view", { ref: (ref) => this._formView = ref, fields: this.fields, onEzContentReady: evt => this.bindFields(evt.detail), singleColumn: this._singleColumn, customUiBuilders: this.customUiBuilders, formLayout: this._currentFormLayout }), this.fieldSearch && h("ez-popover", { ref: elem => (this._ezPopoverFieldColumn = elem), overlayType: "none" }, this.fieldSearch)));
  }
  static get is() { return "snk-dynaform-form-view"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() {
    return {
      "$": ["snk-dynaform-form-view.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["snk-dynaform-form-view.css"]
    };
  }
  static get properties() {
    return {
      "fieldSearch": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "HTMLEzSearchElement",
          "resolved": "HTMLEzSearchElement",
          "references": {
            "HTMLEzSearchElement": {
              "location": "global"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Campo para o buscador de campos."
        }
      },
      "label": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Texto para ser apresentado como t\u00EDtulo do componente"
        },
        "attribute": "label",
        "reflect": false
      },
      "name": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Identificador \u00FAnico do componente, esse \u00E9 utilizado para identificar o\ncomponente no evento de `snkContentCardChanged`"
        },
        "attribute": "name",
        "reflect": false
      },
      "fields": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "Array<IFormViewField>",
          "resolved": "IFormViewField[]",
          "references": {
            "Array": {
              "location": "global"
            },
            "IFormViewField": {
              "location": "import",
              "path": "@sankhyalabs/ezui/dist/types/components/ez-form-view/interfaces/IFormViewField"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Lista de campos para serem apresentados\nno formul\u00E1rio."
        }
      },
      "formMetadata": {
        "type": "any",
        "mutable": false,
        "complexType": {
          "original": "FormMetadata",
          "resolved": "FormMetadata",
          "references": {
            "FormMetadata": {
              "location": "import",
              "path": "@sankhyalabs/ezui/dist/collection/utils/form"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Metadados de campos que definem quais campos s\u00E3o obrigat\u00F3rios,\nquais devem ser limpos durante a c\u00F3pia de registros e valores\npad\u00F5es dos campos."
        },
        "attribute": "form-metadata",
        "reflect": false
      },
      "dataUnit": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "DataUnit",
          "resolved": "DataUnit",
          "references": {
            "DataUnit": {
              "location": "import",
              "path": "@sankhyalabs/core"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Define a inst\u00E2ncia do DataUnit que deve se ligar ao formul\u00E1rio."
        }
      },
      "recordsValidator": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "IRecordValidator",
          "resolved": "IRecordValidator",
          "references": {
            "IRecordValidator": {
              "location": "import",
              "path": "@sankhyalabs/ezui/dist/types/utils/form/interfaces"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Validador respons\u00E1vel por checar a integridade das informa\u00E7\u00F5es do registro."
        }
      },
      "fieldToFocus": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Determina o campo que deve ficar em evid\u00EAncia."
        },
        "attribute": "field-to-focus",
        "reflect": false
      },
      "customEditors": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "PropsCustomEditor",
          "resolved": "PropsCustomEditor",
          "references": {
            "PropsCustomEditor": {
              "location": "import",
              "path": "../../interfaces/PropsCustomEditor"
            }
          }
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Registra um editor customizado para campos da grade e formul\u00E1rio."
        }
      },
      "fieldsProps": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "object",
          "resolved": "object",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Lista de propriedades que ser\u00E3o alteradas/adicionadas por coluna."
        }
      },
      "entityPath": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Determina todo o caminho de entidades."
        },
        "attribute": "entity-path",
        "reflect": false
      }
    };
  }
  static get states() {
    return {
      "_singleColumn": {},
      "_currentFormLayout": {}
    };
  }
  static get events() {
    return [{
        "method": "snkContentCardChanged",
        "name": "snkContentCardChanged",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando a configura\u00E7\u00E3o do card \u00E9 alterada."
        },
        "complexType": {
          "original": "{ formName: string, cardConfig: IFormCardConfig, propertyChanged: string }",
          "resolved": "{ formName: string; cardConfig: IFormCardConfig; propertyChanged: string; }",
          "references": {
            "IFormCardConfig": {
              "location": "import",
              "path": "@sankhyalabs/ezui/dist/types/utils/form/interfaces"
            }
          }
        }
      }, {
        "method": "snkRequestClearFieldToFocus",
        "name": "snkRequestClearFieldToFocus",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando o campo recebe foco"
        },
        "complexType": {
          "original": "void",
          "resolved": "void",
          "references": {}
        }
      }];
  }
  static get methods() {
    return {
      "showUp": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "",
          "tags": []
        }
      },
      "addCustomEditor": {
        "complexType": {
          "signature": "(fieldName: string, customEditor: ICustomEditor, detailContext?: string) => Promise<void>",
          "parameters": [{
              "tags": [],
              "text": ""
            }, {
              "tags": [],
              "text": ""
            }, {
              "tags": [],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            },
            "ICustomEditor": {
              "location": "import",
              "path": "@sankhyalabs/ezui/dist/types/utils/customEditor/interfaces/ICustomEditor"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Registra um editor customizado para campos da grade e formul\u00E1rio",
          "tags": []
        }
      },
      "setFieldProp": {
        "complexType": {
          "signature": "(fieldName: string, propName: string, value: any) => Promise<void>",
          "parameters": [{
              "tags": [],
              "text": ""
            }, {
              "tags": [],
              "text": ""
            }, {
              "tags": [],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Altera/adiciona uma propriedade nos metadados do campo.",
          "tags": []
        }
      },
      "showSearchField": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Exibe a busca de campos ancorada ao container de cabe\u00E7alho do snk-dynaform-form-view.",
          "tags": []
        }
      }
    };
  }
  static get watchers() {
    return [{
        "propName": "customEditors",
        "methodName": "observePropsCustomEditor"
      }, {
        "propName": "fieldsProps",
        "methodName": "observeFieldsProps"
      }, {
        "propName": "dataUnit",
        "methodName": "observeDataUnit"
      }];
  }
}
