/* COPYRIGHT Esri - https://js.arcgis.com/1.2/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { ref } from "lit/directives/ref.js";
import { css, html } from "lit";
import { u as useT9n } from "../../chunks/useT9n.js";
import { LitElement } from "@arcgis/lumina";
import "../layer-table/customElement.js";
const styles = css`/** @license
 * Copyright 2025 Esri
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

.height-51 {
  height: 51px;
}

.width-51 {
  width: 51px;
}`;
class FieldSelection extends LitElement {
  constructor() {
    super();
    this._translations = useT9n({ name: "field-selection", blocking: true });
    this._fieldSortOrder = "default";
    this._selectedFields = [];
    this._fieldVisibilityPopoverClickHandler = (event) => {
      if (!this._fieldVisibilityPopoverNode) {
        document.removeEventListener("click", this._fieldVisibilityPopoverClickHandler);
      } else if (!this._isInNode(event.target, "arcgis-field-pick-list")) {
        document.body.removeChild(this._fieldVisibilityPopoverNode);
        this._fieldVisibilityPopoverNode = void 0;
        document.removeEventListener("click", this._fieldVisibilityPopoverClickHandler);
      }
    };
    this.listenOn(window, "columnReorder", this.handleColumnReorder, { capture: true });
  }
  static {
    this.properties = { configExtraFields: 1, layer: [0, {}, { attribute: false }], mapView: [0, {}, { attribute: false }], table: [0, {}, { attribute: false }], tableRef: [0, {}, { attribute: false }], _translations: [16, {}, { state: true }] };
  }
  static {
    this.styles = styles;
  }
  render() {
    return html`<calcite-action alignment=center appearance=solid class="height-51 width-51" id=solutions-field-selection .text=${this._translations.fieldVisibility} scale=m @click=${() => this._handleFieldVisibilityClick()} @mouseover=${() => this._addTableTooltip(this._fieldVisibilityActionNode, this._translations.fieldVisibility)} @mouseout=${() => this._removeTableTooltip()} @focus=${() => this._addTableTooltip(this._fieldVisibilityActionNode, this._translations.fieldVisibility)} ${ref((node) => this._fieldVisibilityActionNode = node)}><calcite-icon scale=s icon=gear></calcite-icon></calcite-action>`;
  }
  handleColumnReorder() {
    this._fieldSortOrder = "default";
    if (this._fieldVisibilityPopoverNode) {
      this.removeFieldsPickList();
      this._handleFieldVisibilityClick();
    }
  }
  _handleFieldVisibilityClick() {
    if (this._fieldVisibilityPopoverNode) {
      return;
    }
    const columnTemplates = this.table?.tableTemplate?.columnTemplates;
    if (this.layer && this.mapView && columnTemplates && this._fieldVisibilityActionNode) {
      document.removeEventListener("click", this._fieldVisibilityPopoverClickHandler);
      const fields = this.table.fieldColumns.map((c) => {
        return {
          alias: c.field.alias,
          description: c.field.description,
          name: c.field.name,
          type: c.field.type
        };
      });
      if (this._hasAttachmentsEnabled(this.layer)) {
        const attachments = "Attachments";
        if (this._shouldShowField(attachments.toUpperCase(), false)) {
          if (!columnTemplates.some((ct) => ct.fieldName.toUpperCase() === attachments.toUpperCase())) {
            const attachmentColumnTemplate = {
              fieldName: attachments,
              type: "attachment",
              visible: true
            };
            columnTemplates.push(attachmentColumnTemplate);
          }
          fields.push({
            name: attachments,
            alias: "Photos and files",
            type: "none",
            description: attachments
          });
        }
      }
      const relationshipEnabled = this.table.relatedRecordsEnabled;
      if (relationshipEnabled && this.layer.relationships && this.layer.relationships.length > 0) {
        const parent = this.layer.parent;
        this.layer.relationships.forEach((rel) => {
          let name;
          let shouldPush = this._shouldShowField(rel.name || "", true);
          if (!columnTemplates.some((ct) => {
            if (ct.fieldName.toLowerCase() === rel.name?.toLowerCase()) {
              name = rel.name;
              return true;
            } else {
              return false;
            }
          })) {
            if (rel.name) {
              name = rel.name;
              const relationshipColumnTemplate = {
                fieldName: name,
                type: "relationship",
                visible: true
              };
              shouldPush = this._shouldShowField(name, true);
              columnTemplates.push(relationshipColumnTemplate);
            } else {
              const allLayersAndTables = [...parent?.layers || [], ...parent?.tables];
              let relItem;
              allLayersAndTables.some((lt) => {
                if (lt.layerId === rel.relatedTableId) {
                  relItem = lt;
                  return true;
                }
                return false;
              });
              if (relItem) {
                name = relItem.title;
                rel.name = name;
                const relationshipColumnTemplate = {
                  fieldName: name,
                  type: "relationship",
                  visible: true
                };
                shouldPush = this._shouldShowField(name, true);
                columnTemplates.push(relationshipColumnTemplate);
              }
            }
          }
          if (name && shouldPush) {
            fields.push({
              name,
              alias: `Related ${name}`,
              type: "none",
              description: `related:${name}`
            });
          }
        });
      }
      const popover = !this._fieldVisibilityPopoverNode ? document.createElement("arcgis-field-pick-list") : this._fieldVisibilityPopoverNode;
      popover.layer = this.layer;
      popover.fields = fields;
      popover.showFieldInfo = true;
      popover.showFieldName = true;
      popover.showDescription = false;
      popover.showSelectionAll = true;
      popover.hideCancel = true;
      popover.hideSort = false;
      popover.showFilterLength = 5;
      popover.multiple = true;
      popover.heading = this._translations.fieldVisibility;
      popover.okBtnText = this._translations.doneWithFieldChanges;
      popover.filterPlaceholderText = this._translations.filterFields;
      popover.sortBy = this._fieldSortOrder ?? "default";
      const visibleFields = this.table?.visibleColumns.map((vc) => {
        return vc.fieldName.startsWith("EsriFeatureTableRelationshipColumn") ? vc.effectiveLabel : vc.fieldName.startsWith("EsriFeatureTableAttachmentsColumn") ? vc.effectiveLabel : vc.fieldName;
      });
      popover.selectedFields = columnTemplates.reduce((prev, cur) => {
        if (visibleFields ? visibleFields.indexOf(cur.fieldName) > -1 : cur.visible) {
          prev.push(cur.fieldName);
        }
        return prev;
      }, []);
      this._selectedFields = popover.selectedFields;
      popover.style.minHeight = "340px";
      popover.popoverProps = {
        refElement: this._fieldVisibilityActionNode,
        popoverWidth: 300,
        placement: "bottom-end",
        offsetDistance: -20,
        triggerDisabled: false,
        autoClose: false
      };
      popover.addEventListener("arcgisChange", (event) => {
        event.stopPropagation();
        const updatedFieldNames = event.detail.selectedFields;
        const added = this._getDifference(updatedFieldNames, this._selectedFields);
        const removed = this._getDifference(this._selectedFields, updatedFieldNames);
        const diffs = added.concat(removed);
        diffs.forEach((fieldName) => {
          const relationships = this.layer?.relationships?.map((rel) => rel.name) || [];
          if (fieldName === "Attachments") {
            const attachmentsColumn = this.table.columns.find((column) => "onShowAttachments" in column);
            attachmentsColumn.hidden = removed.indexOf(fieldName) > -1;
          } else if (relationships.indexOf(fieldName) > -1) {
            const relationshipColumns = this.table.columns.filter((column) => "relationshipId" in column);
            relationshipColumns.forEach((relationshipColumn) => {
              removed.indexOf(fieldName) > -1;
              if (fieldName == relationshipColumn.effectiveLabel) {
                relationshipColumn.hidden = removed.indexOf(fieldName) > -1;
              }
            });
          } else {
            this.table.toggleColumnVisibility(fieldName);
          }
        });
        this._selectedFields = updatedFieldNames;
        this._updateTable(this.table.tableTemplate);
      });
      popover.addEventListener("arcgisSortByChange", (event) => {
        event.stopPropagation();
        this._fieldSortOrder = event.detail;
        this._sortFields(event.detail);
      });
      popover.addEventListener("arcgisClose", () => {
        this._closePopovers();
        setTimeout(() => this._fieldVisibilityActionNode.setFocus(), 200);
      });
      document.body.appendChild(popover);
      this._fieldVisibilityPopoverNode = popover;
      setTimeout(() => document.addEventListener("click", this._fieldVisibilityPopoverClickHandler), 200);
    }
  }
  _shouldShowField(name, isRelatedField) {
    return (this.configExtraFields || []).some((f) => isRelatedField ? f.replace("related:", "").toUpperCase() === name.toUpperCase() : f.toUpperCase() === name.toUpperCase());
  }
  removeFieldsPickList() {
    if (this._fieldVisibilityPopoverNode) {
      document.body.removeChild(this._fieldVisibilityPopoverNode);
      this._fieldVisibilityPopoverNode = void 0;
    }
  }
  _sortFields(type) {
    const columnTemplates = this.table.tableTemplate.columnTemplates;
    const order = this._getSortOrder(type);
    const columns = columnTemplates.filter((_ct) => {
      return _ct.type !== "attachment" && _ct.type !== "relationship";
    });
    const sortedColumns = columns.sort((a, b) => {
      const indexA = order.indexOf(a.fieldName);
      const indexB = order.indexOf(b.fieldName);
      if (indexA === -1 && indexB !== -1)
        return 1;
      if (indexA !== -1 && indexB === -1)
        return -1;
      if (indexA === -1 && indexB === -1)
        return 0;
      return indexA - indexB;
    });
    const specialColumns = columnTemplates.filter((_ct) => {
      return _ct.type === "attachment" || _ct.type === "relationship";
    });
    this.tableRef.setColumnOrder([...sortedColumns, ...specialColumns]);
    this._updateTable(this.table.tableTemplate);
  }
  _getSortOrder(lastSortBy) {
    const tempSorted = [...this.layer.fields];
    if (lastSortBy === "display") {
      tempSorted.sort((a, b) => a.alias.localeCompare(b.alias));
    } else if (lastSortBy === "field") {
      tempSorted.sort((a, b) => a.name.localeCompare(b.name));
    } else if (lastSortBy === "type") {
      tempSorted.sort((a, b) => a.type.localeCompare(b.type));
    }
    return tempSorted.map((t) => t.name);
  }
  _getDifference(a, b) {
    return a.filter((s) => !b.includes(s));
  }
  _updateTable(tableTemplate) {
    this.table.tableTemplate = tableTemplate;
    if (this._isStandardView()) {
      this._syncAttributeTableTemplate();
    }
  }
  async _syncAttributeTableTemplate() {
    const layer = this.table.layer;
    if (layer.attributeTableTemplate) {
      const { _modules } = this;
      const updatedAttributeTableTemplate = layer.attributeTableTemplate.clone();
      _modules?.attributeTableTemplateUtils.syncAttributeTableTemplate(this.table, updatedAttributeTableTemplate);
      if (JSON.stringify(updatedAttributeTableTemplate) !== JSON.stringify(layer.attributeTableTemplate)) {
        layer.attributeTableTemplate = updatedAttributeTableTemplate;
      }
    }
    if (layer.attributeTableTemplate?.orderByFields?.length > 1) {
      const updatedAttributeTableTemplate = layer.attributeTableTemplate.clone();
      const activeSortField = this.table.activeSortOrders[0];
      updatedAttributeTableTemplate.orderByFields = [
        { field: activeSortField.fieldName, order: activeSortField.direction }
      ];
      layer.attributeTableTemplate = updatedAttributeTableTemplate;
      this._syncColumnDirectionsWithOrderByFields();
    }
  }
  _syncColumnDirectionsWithOrderByFields() {
    const currentSortFieldName = this.table.activeSortOrders[0]?.fieldName;
    this.table.columns.forEach((column) => {
      if ("fieldName" in column && column.fieldName !== currentSortFieldName) {
        column.direction = void 0;
      }
    });
    this.table.tableTemplate?.columnTemplates.forEach((template) => {
      if ("fieldName" in template && template.fieldName !== currentSortFieldName) {
        template.direction = void 0;
      }
    });
  }
  _isStandardView() {
    return !this.table.relatedTable && !this.table.attachmentsViewOptions.objectId;
  }
  _closePopovers() {
    document.removeEventListener("click", this._fieldVisibilityPopoverClickHandler);
    if (this._fieldVisibilityPopoverNode) {
      document.body.removeChild(this._fieldVisibilityPopoverNode);
      this._fieldVisibilityPopoverNode = void 0;
    }
  }
  _addTableTooltip(node, message) {
    const tooltip = document.createElement("calcite-tooltip");
    tooltip.className = "table-tooltip";
    tooltip.referenceElement = node;
    tooltip.placement = "trailing-start";
    tooltip.open = true;
    const div = document.createElement("div");
    div.className = "tooltip";
    div.innerHTML = message;
    tooltip.append(div);
    document.body.append(tooltip);
  }
  _removeTableTooltip() {
    document.querySelectorAll(".table-tooltip").forEach((tooltip) => tooltip.parentNode?.removeChild(tooltip));
  }
  _isInNode(node, nodeName) {
    while (node) {
      if (node.nodeName === nodeName.toUpperCase()) {
        return true;
      }
      node = node.parentElement;
    }
    return false;
  }
  _hasAttachmentsEnabled(layer) {
    if (!layer?.capabilities) {
      return false;
    }
    const { capabilities: { data: { supportsAttachment }, operations: { supportsQueryAttachments } } } = layer;
    return supportsAttachment && supportsQueryAttachments;
  }
}
customElement("field-selection", FieldSelection);
export {
  FieldSelection
};
