import { DateUtils, ElementIDUtils, KeyboardManager, MaskFormatter } from '@sankhyalabs/core';
import { h, Host } from '@stencil/core';
import { FilterNumberVariation } from './editors/enum/filterNumberVariation';
import FilterItemType from './filter-item-type.enum';
export class SnkFilterItem {
  constructor() {
    this._keyboardManager = undefined;
    this.detailIsVisible = undefined;
    this.config = undefined;
    this.getMessage = undefined;
    this.showChips = true;
  }
  observeDetailIsVisible(value) {
    this.visibleChanged.emit(value);
  }
  /**
   * Emitido quando o estado do filtro é alterado.
   */
  filterChangeListener(_event) {
    this.hideDetail();
  }
  /**
   * Exibe os detalhes de um item da lista.
   */
  async showUp(open = false) {
    var _a;
    this._filterItemElement.scrollIntoView({ behavior: "auto", block: "nearest", inline: "nearest" });
    if (open) {
      await ((_a = this._chipElement) === null || _a === void 0 ? void 0 : _a.setBlur());
      await this._popover.showUnder(this._chipElement);
      await this._filterDetail.setFocusField();
    }
  }
  /**
   * Oculta os detalhes de um item da lista.
   */
  async hideDetail() {
    var _a;
    await ((_a = this._popover) === null || _a === void 0 ? void 0 : _a.hide());
  }
  getConfigChanges() {
    var _a;
    const configToBeCleared = this.config;
    if (!!((_a = configToBeCleared.groupedItems) === null || _a === void 0 ? void 0 : _a.length)) {
      configToBeCleared.visible = false;
      configToBeCleared.groupedItems = configToBeCleared.groupedItems.map(item => (Object.assign(Object.assign({}, item), { visible: false })));
    }
    const hasMultiValues = configToBeCleared.type === FilterItemType.MULTI_LIST && Array.isArray(configToBeCleared.value);
    const newValue = hasMultiValues ? configToBeCleared.value.map((valueItem) => (Object.assign(Object.assign({}, valueItem), { check: false }))) : undefined;
    return Object.assign(Object.assign({}, configToBeCleared), { value: newValue });
  }
  clearFilter(event) {
    event === null || event === void 0 ? void 0 : event.stopPropagation();
    if (this.canClearFilter()) {
      const configChanged = this.getConfigChanges();
      this.filterChange.emit(configChanged);
    }
    else {
      this.togglePopover(event);
    }
  }
  async togglePopover(event) {
    event === null || event === void 0 ? void 0 : event.preventDefault();
    event === null || event === void 0 ? void 0 : event.stopPropagation();
    if (this.config.enabled === false) {
      return;
    }
    if (this.detailIsVisible) {
      await this.hideDetail();
    }
    else {
      await this.showUp(true);
    }
  }
  getLabel(isTooltipLabel = false) {
    var _a, _b;
    const { type, value, label, props, groupedItems = [] } = this.config;
    if (value || groupedItems.length) {
      if (type === FilterItemType.BINARY_SELECT) {
        const [optOne, optTwo] = props.options;
        const tooltip = this.getMessage('snkFilterBar.binarySelectTooltip');
        if (optOne.name === value) {
          return isTooltipLabel ? `${tooltip} ${String(optOne.label).toLowerCase()}` : optOne.label;
        }
        if (optTwo.name === value) {
          return isTooltipLabel ? `${tooltip} ${String(optTwo.label).toLowerCase()}` : optTwo.label;
        }
      }
      if (type === FilterItemType.MULTI_SELECT) {
        const opt = props.options.find(opt => opt.value === value);
        return `${label}: ${opt.label}`;
      }
      if (type === FilterItemType.PERIOD) {
        let { end, start } = value;
        if (typeof end === "string") {
          end = new Date(end);
          end.setMinutes(end.getMinutes() + end.getTimezoneOffset());
        }
        if (typeof start === "string") {
          start = new Date(start);
          start.setMinutes(start.getMinutes() + start.getTimezoneOffset());
        }
        const dateFormater = new Intl.DateTimeFormat("pt-BR");
        if (end && start) {
          const isSameYear = start.getFullYear() === end.getFullYear();
          const formatOptions = Object.assign({ day: '2-digit', month: '2-digit' }, ((!isSameYear || isTooltipLabel) && { year: '2-digit' }));
          const startLabel = DateUtils.formatDate(start, formatOptions);
          const endLabel = DateUtils.formatDate(end, formatOptions);
          if (isTooltipLabel) {
            return this.getMessage('snkFilterBar.fullPeriodTooltip', { LABEL: label, START_LABEL: startLabel, END_LABEL: endLabel });
          }
          return `${label}: ${startLabel} \u2192 ${endLabel}`;
        }
        else {
          if (start) {
            return `${label}: ${this.getMessage('snkFilterBar.onlyStartToltip')} ${dateFormater.format(start)}`;
          }
          else if (end) {
            return `${label}: ${this.getMessage('snkFilterBar.onlyEndToltip')} ${dateFormater.format(end)}`;
          }
          else {
            return label;
          }
        }
      }
      if (type === FilterItemType.SEARCH) {
        return `${label}: ${value.value} - ${value.label}`;
      }
      if (type === FilterItemType.PERSONALIZED) {
        const activeCount = this.calculateActiveCount(groupedItems);
        if (activeCount <= 0)
          return label;
        return `${label}: ${this.getMessage('snkFilterBar.personalizedCount', { activeCount })}`;
      }
      if (type === FilterItemType.MULTI_LIST) {
        const selectedOptions = ((_a = value.elements) !== null && _a !== void 0 ? _a : value).filter(item => item === null || item === void 0 ? void 0 : item.check);
        return this.getLabelFromCheckedOptions(selectedOptions, label, isTooltipLabel);
      }
      if (type === FilterItemType.CHECK_BOX_LIST) {
        const selectedValues = Object.entries(value !== null && value !== void 0 ? value : {})
          .filter(([_, value]) => value === true)
          .map(([key, _]) => key);
        const options = (_b = props.options) !== null && _b !== void 0 ? _b : [];
        const selectedOptions = options.filter(option => selectedValues.includes(option.name));
        return this.getLabelFromCheckedOptions(selectedOptions, label, isTooltipLabel);
      }
      if (type === FilterItemType.NUMBER && props.variation === FilterNumberVariation.INTERVAL) {
        const { start, end } = value;
        if (!isNaN(start) && !isNaN(end)) {
          return this.getMessage('snkFilterBar.fullIntervalTooltip', { LABEL: label, START_LABEL: start, END_LABEL: end });
        }
        if (!isNaN(start)) {
          return `${label}: ${this.getMessage('snkFilterBar.onlyStartToltip')} ${Number(start)}`;
        }
        if (!isNaN(end)) {
          return `${label}: ${this.getMessage('snkFilterBar.onlyEndToltip')} ${Number(end)}`;
        }
      }
      if (this.config.mask) {
        const _maskFormatter = new MaskFormatter(this.config.mask);
        return `${label}: ${_maskFormatter.format(value)}`;
      }
      return `${label}: ${value}`;
    }
    return label;
  }
  getLabelFromCheckedOptions(selectedOptions, label, isTooltipLabel) {
    const checkedAmount = selectedOptions.length;
    if (checkedAmount === 0) {
      return `${label}`;
    }
    if (checkedAmount > 1) {
      if (isTooltipLabel) {
        const selectedOptionsDescrptions = selectedOptions.map(item => item.label);
        return `${label}: ${selectedOptionsDescrptions.join(',')}`;
      }
      return `${label}: ${checkedAmount} ${this.getMessage('snkFilterBar.multiListToltip')}`;
    }
    return `${label}: ${selectedOptions[0].label}`;
  }
  calculateActiveCount(groupedItems) {
    return groupedItems.reduce((total, item) => {
      if (!!item.visible)
        return total + 1;
      return total;
    }, 0);
  }
  componentDidLoad() {
    if (this._filterItemElement) {
      ElementIDUtils.addIDInfo(this._filterItemElement);
      this._idSnkFilterDetail = `filterDetail_${this.config.id}`;
    }
  }
  canClearFilter() {
    const { value, groupedItems = [] } = this.config;
    if (value != undefined && this.config.type === FilterItemType.MULTI_LIST) {
      return value.some((item) => item.check);
    }
    return value !== undefined || groupedItems.some(item => item.visible);
  }
  getRightIconName() {
    if (this.canClearFilter())
      return "close";
    return this.detailIsVisible ? "chevron-up" : "chevron-down";
  }
  getLeftIconName() {
    switch (this.config.type) {
      case FilterItemType.PERIOD:
        return "calendar";
      case FilterItemType.PERSONALIZED:
        return "tune";
    }
    return undefined;
  }
  hasActiveElements(value) {
    var _a;
    const list = Array.isArray(value) ? value : value === null || value === void 0 ? void 0 : value.elements;
    return ((_a = list === null || list === void 0 ? void 0 : list.filter((val) => val === null || val === void 0 ? void 0 : val.check)) === null || _a === void 0 ? void 0 : _a.length) > 0;
  }
  hasActiveValue(config) {
    var _a, _b;
    if (config.type === FilterItemType.PERIOD) {
      return (!!((_a = config.value) === null || _a === void 0 ? void 0 : _a.start) || !!((_b = config.value) === null || _b === void 0 ? void 0 : _b.end));
    }
    return (config.type !== FilterItemType.MULTI_LIST && config.value !== undefined) || this.hasActiveElements(config.value);
  }
  getEnabledChip() {
    if (this.detailIsVisible) {
      return true;
    }
    if (this.config.type === FilterItemType.PERSONALIZED) {
      const { groupedItems = [] } = this.config;
      return groupedItems.some(item => item.visible);
    }
    return this.hasActiveValue(this.config);
  }
  async handleVisibilityPopover(event) {
    this.detailIsVisible = event.detail;
    if (!this.detailIsVisible) {
      await this._filterDetail.clearValue();
    }
  }
  getCustomMessage(key, params) {
    var _a;
    return (_a = this.getMessage) === null || _a === void 0 ? void 0 : _a.call(this, `snkFilterBar.filterModal.${key}`, params);
  }
  hasValue() {
    if (this.config.type === FilterItemType.MULTI_LIST) {
      return this.hasActiveElements(this.config.value);
    }
    return this.config.value !== undefined && this.config.value !== null;
  }
  getTooltipMessage() {
    var _a, _b;
    if (this.config.required && !this.hasValue()) {
      return {
        message: (_a = this.config.requiredMessage) !== null && _a !== void 0 ? _a : this.getCustomMessage('validations.requiredFilter'),
        type: 'error'
      };
    }
    if (this.config.enabled === false && this.config.disabledMessage) {
      return { message: this.config.disabledMessage, type: 'warning' };
    }
    return {
      message: (_b = this.config.defaultMessage) !== null && _b !== void 0 ? _b : this.getLabel(true),
      type: 'default'
    };
  }
  getTypeChip(type) {
    switch (type) {
      case 'default':
        return 'secondary';
      case 'warning':
        return 'warning-light';
      case 'error':
        return 'error-light';
      case 'success':
        return 'success-light';
      default:
        return type;
    }
  }
  initKeyboardManager() {
    this._keyboardManager = new KeyboardManager({ element: this._filterItemElement, propagate: true });
    this._keyboardManager
      .bind("Escape", () => this.hideDetail());
  }
  connectedCallback() {
    this.initKeyboardManager();
  }
  disconnectedCallback() {
    this._keyboardManager.unbindAllShortcutKeys();
  }
  render() {
    const leftIcon = this.getLeftIconName();
    const { type, message } = this.getTooltipMessage();
    return (h(Host, null, this.showChips && (h("ez-tooltip", { id: this.config.id, message: message, type: type, active: !this.detailIsVisible, strategy: "fixed" }, h("ez-chip", { id: this.config.id, ref: ref => this._chipElement = ref, label: this.getLabel(), value: this.getEnabledChip(), onClick: (event) => this.togglePopover(event), disableAutoUpdateValue: true, type: this.getTypeChip(type), enabled: this.config.enabled }, leftIcon && (h("ez-icon", { ref: ref => this._leftIconElement = ref, iconName: leftIcon, slot: "leftIcon" })), h("ez-icon", { ref: ref => this._rightIconElement = ref, iconName: this.getRightIconName(), slot: "rightIcon", id: "removeFilter", onClick: (event) => this.clearFilter(event) })))), h("ez-popover-core", { ref: elem => this._popover = elem, onEzVisibilityChange: (event) => this.handleVisibilityPopover(event) }, h("snk-filter-detail", { ref: ref => this._filterDetail = ref, key: this.config.id, config: this.config, getMessage: this.getMessage, class: "sc-snk-filter-bar snk-filter__popover ez-padding--small ez-elevation--16", "data-element-id": this._idSnkFilterDetail, showHardFixed: this.showChips && !this.config.required, removalBlocked: this.config.required }))));
  }
  static get is() { return "snk-filter-item"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() {
    return {
      "$": ["snk-filter-item.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["snk-filter-item.css"]
    };
  }
  static get properties() {
    return {
      "config": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "SnkFilterItemConfig",
          "resolved": "SnkFilterItemConfig",
          "references": {
            "SnkFilterItemConfig": {
              "location": "local"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Define as configura\u00E7\u00F5es do componente snk-filter-item."
        }
      },
      "getMessage": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "(key: string, props?: any) => string",
          "resolved": "(key: string, props?: any) => string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Usado pra flexibilizar os verbetes e mensagens de acordo com o SnkMessageBuilder."
        }
      },
      "showChips": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Usado para controlar a visibilidade dos chips de filtros"
        },
        "attribute": "show-chips",
        "reflect": false,
        "defaultValue": "true"
      }
    };
  }
  static get states() {
    return {
      "detailIsVisible": {}
    };
  }
  static get events() {
    return [{
        "method": "visibleChanged",
        "name": "visibleChanged",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando o detalhe de um item da lista \u00E9 aberto ou fechado."
        },
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        }
      }, {
        "method": "filterChange",
        "name": "filterChange",
        "bubbles": false,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitido quando h\u00E1 uma altera\u00E7\u00E3o nos filtros."
        },
        "complexType": {
          "original": "SnkFilterItemConfig",
          "resolved": "SnkFilterItemConfig",
          "references": {
            "SnkFilterItemConfig": {
              "location": "local"
            }
          }
        }
      }];
  }
  static get methods() {
    return {
      "showUp": {
        "complexType": {
          "signature": "(open?: boolean) => Promise<void>",
          "parameters": [{
              "tags": [],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Exibe os detalhes de um item da lista.",
          "tags": []
        }
      },
      "hideDetail": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Oculta os detalhes de um item da lista.",
          "tags": []
        }
      }
    };
  }
  static get elementRef() { return "_filterItemElement"; }
  static get watchers() {
    return [{
        "propName": "detailIsVisible",
        "methodName": "observeDetailIsVisible"
      }];
  }
  static get listeners() {
    return [{
        "name": "filterChange",
        "method": "filterChangeListener",
        "target": undefined,
        "capture": false,
        "passive": false
      }];
  }
}
