import { ApplicationContext, ElementIDUtils } from "@sankhyalabs/core";
import { Host, h } from "@stencil/core";
import { DataBinder } from "@sankhyalabs/ezui/dist/collection/utils/form";
import { focusOnFieldSerch, SEARCH_FIELD_FULL_WIDTH, FormLayout } from '@sankhyalabs/ezui/dist/collection/utils';
export class SnkFormView {
  constructor() {
    this._customEditors = new Map();
    this._fieldProps = new Map();
    this._singleColumn = false;
    this.levelPath = undefined;
    this.fieldSearch = undefined;
    this.label = undefined;
    this.name = undefined;
    this.fields = undefined;
    this.formMetadata = undefined;
    this.dataUnit = undefined;
    this.contracted = undefined;
    this.fixed = false;
    this.summaryFields = undefined;
    this.canExpand = true;
    this.canFix = true;
    this.recordsValidator = undefined;
    this.fieldToFocus = undefined;
    this.customEditors = undefined;
    this.fieldsProps = undefined;
  }
  async showUp() {
    if (this._formView) {
      this._formView.showUp();
    }
  }
  /**
   * Registra um editor customizado para campos da grade e formulário
   */
  async addCustomEditor(fieldName, customEditor, detailContext) {
    if (this._formView) {
      this._formView.addCustomEditor(fieldName, customEditor, detailContext);
      return;
    }
    const newCustomEditors = new Map(this._customEditors);
    newCustomEditors.set(fieldName, { customEditor, 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-form-view.
   */
  async showSearchField() {
    if (!this._headerContainer || !this._ezPopoverFieldColumn)
      return;
    const container = this._headerContainer.getBoundingClientRect();
    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]);
      }
    }
  }
  changeFix() {
    this.fixed = !this.fixed;
    this.emitEvent("fixed");
  }
  changeContracted() {
    this.contracted = !this.contracted;
    this.emitEvent("presentation");
  }
  emitEvent(propertyChanged) {
    this.snkContentCardChanged.emit({
      formName: this.name,
      cardConfig: {
        fixed: this.fixed,
        presentation: this.contracted ? "CONTRACTED" : "EXPANDED"
      },
      propertyChanged
    });
  }
  getCardSummary() {
    const summary = {};
    this.getSummaryFields().forEach(({ field, label }) => {
      var _a;
      const value = this.dataUnit.getFormattedValue(field);
      if (value !== "") {
        if (label == undefined) {
          label = (_a = this.dataUnit.getField(field)) === null || _a === void 0 ? void 0 : _a.label;
        }
        summary[label] = value;
      }
    });
    return summary;
  }
  getSummaryFields() {
    if (this.summaryFields == undefined) {
      return this.fields.map(field => {
        const descriptor = this.dataUnit.getField(field.name);
        return { field: field.name, label: field.label || (descriptor === null || descriptor === void 0 ? void 0 : descriptor.label) };
      });
    }
    return this.summaryFields;
  }
  bindFields(fields) {
    if (this._dataBinder == undefined && this.dataUnit != undefined) {
      this._dataBinder = new DataBinder(this.dataUnit);
    }
    if (this._dataBinder) {
      this._dataBinder.bind(fields, this.dataUnit.dataUnitId, this.formMetadata, this.recordsValidator);
    }
  }
  handleFormItemsReady(event) {
    event.stopPropagation();
    this.formItemsReady.emit(Object.assign(Object.assign({}, event.detail), { formId: this.name }));
  }
  disconnectedCallback() {
    if (this._dataBinder != undefined) {
      this._dataBinder.onDisconnectedCallback();
    }
  }
  componentDidLoad() {
    this.observePropsCustomEditor(this.customEditors);
    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) {
    if (!layoutFormConfig)
      return;
    layoutFormConfig.onConfigChange((config) => {
      this._singleColumn = (config === FormLayout.CASCADE);
    });
  }
  componentDidRender() {
    this.setCustomEditors();
    this.setFieldProps();
    if (this.fieldToFocus == undefined) {
      return;
    }
    if (!this.fields.some(item => item.name === this.fieldToFocus)) {
      return;
    }
    requestAnimationFrame(() => {
      this._dataBinder.setFocus(this.fieldToFocus);
      this.snkRequestClearFieldToFocus.emit();
    });
  }
  setCustomEditors() {
    if (!this._formView) {
      return;
    }
    for (const [fieldName, customEditorProps] of this._customEditors) {
      this._formView.addCustomEditor(fieldName, customEditorProps.customEditor, customEditorProps.detailContext);
      this._customEditors.delete(fieldName);
    }
  }
  setFieldProps() {
    if (!this._formView) {
      return;
    }
    for (const [fieldName, propsToChange] of this._fieldProps) {
      propsToChange.forEach(prop => {
        this._formView.setFieldProp(fieldName, prop.propName, prop.value);
        this._fieldProps.delete(fieldName);
      });
    }
  }
  render() {
    return (h(Host, { class: "ez-box__container" }, h("div", { class: "summary-header ez-flex ez-size-width--full", ref: ref => this._headerContainer = ref }, h("div", { class: "ez-flex ez-text ez-title--primary ez-text--bold ez-flex--justify-start ez-flex--align-items-center ez-col--sd-9" }, this.levelPath ? h("span", { class: "level-path" }, this.levelPath + " /") : undefined, this.label), h("div", { class: "ez-flex ez-flex--justify-end ez-col--sd-3" }, this.canFix &&
      h("ez-button", { class: "ez-padding-left--medium", mode: "icon", size: "small", iconName: this.fixed ? "un-pin" : "push-pin", "data-element-id": ElementIDUtils.getInternalIDInfo("toggleFixed_ezFormCard"), onClick: () => this.changeFix(), title: this.fixed ? "Desafixar" : "Fixar" }), this.canExpand &&
      h("ez-button", { class: "ez-padding-left--medium", mode: "icon", size: "small", iconName: this.contracted ? "chevron-down" : "chevron-up", "data-element-id": ElementIDUtils.getInternalIDInfo("toggleExpand_ezFormCard"), onClick: () => this.changeContracted(), title: this.contracted ? "Expandir" : "Resumir" }))), h("slot", null), this.contracted
      ?
        h("snk-form-summary", { summary: this.getCardSummary() })
      :
        h("ez-form-view", { ref: ref => this._formView = ref, fields: this.fields, onEzContentReady: evt => this.bindFields(evt.detail), onFormItemsReady: (event) => this.handleFormItemsReady(event), singleColumn: this._singleColumn }), this.fieldSearch && h("ez-popover", { ref: elem => (this._ezPopoverFieldColumn = elem), overlayType: "none" }, this.fieldSearch)));
  }
  static get is() { return "snk-form-view"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() {
    return {
      "$": ["snk-form-view.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["snk-form-view.css"]
    };
  }
  static get properties() {
    return {
      "levelPath": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Caminho amig\u00E1vel para se chegar a este detalhe."
        },
        "attribute": "level-path",
        "reflect": false
      },
      "fieldSearch": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "HTMLEzSearchElement",
          "resolved": "HTMLEzSearchElement",
          "references": {
            "HTMLEzSearchElement": {
              "location": "global"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Campo para o buscador de campos."
        }
      },
      "label": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "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": false,
        "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": false,
        "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": false,
        "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": false,
        "docs": {
          "tags": [],
          "text": "Define a inst\u00E2ncia do DataUnit que deve se ligar ao formul\u00E1rio."
        }
      },
      "contracted": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o componente ser\u00E1 apresentado no modo default ou no modo\nresumido."
        },
        "attribute": "contracted",
        "reflect": false
      },
      "fixed": {
        "type": "boolean",
        "mutable": true,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o card est\u00E1 fixado ou n\u00E3o."
        },
        "attribute": "fixed",
        "reflect": true,
        "defaultValue": "false"
      },
      "summaryFields": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "Array<ISummaryField>",
          "resolved": "ISummaryField[]",
          "references": {
            "Array": {
              "location": "global"
            },
            "ISummaryField": {
              "location": "import",
              "path": "@sankhyalabs/ezui/dist/types/utils/form/interfaces"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        }
      },
      "canExpand": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o bot\u00E3o de expandir deve ser apresentado."
        },
        "attribute": "can-expand",
        "reflect": false,
        "defaultValue": "true"
      },
      "canFix": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define se o bot\u00E3o de fixar deve ser apresentado."
        },
        "attribute": "can-fix",
        "reflect": false,
        "defaultValue": "true"
      },
      "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": false,
        "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": false,
        "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": false,
        "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": false,
        "docs": {
          "tags": [],
          "text": "Lista de propriedades que ser\u00E3o alteradas/adicionadas por coluna."
        }
      }
    };
  }
  static get states() {
    return {
      "_singleColumn": {}
    };
  }
  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": {}
        }
      }, {
        "method": "formItemsReady",
        "name": "formItemsReady",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Respons\u00E1vel por notificar quando ocorrer a renderiza\u00E7\u00E3o de itens do formul\u00E1rio."
        },
        "complexType": {
          "original": "Array<HTMLElement>",
          "resolved": "HTMLElement[]",
          "references": {
            "Array": {
              "location": "global"
            },
            "HTMLElement": {
              "location": "global"
            }
          }
        }
      }];
  }
  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-form-view.",
          "tags": []
        }
      }
    };
  }
  static get watchers() {
    return [{
        "propName": "customEditors",
        "methodName": "observePropsCustomEditor"
      }, {
        "propName": "fieldsProps",
        "methodName": "observeFieldsProps"
      }];
  }
}
