/* COPYRIGHT Esri - https://js.arcgis.com/1.2/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { g as getLayerOrTable, d as getMapLayerHash, f as getMapTableHash } from "../../chunks/mapViewUtils.js";
import { u as useT9n } from "../../chunks/useT9n.js";
import { css, html, nothing } from "lit";
import { createRef, ref } from "lit-html/directives/ref.js";
import { LitElement, createEvent, noShadowRoot, safeStyleMap, safeClassMap } from "@arcgis/lumina";
import { useContextConsumer } from "@arcgis/lumina/context";
import { p as pnContext } from "../../chunks/publicNotificationContext.js";
const styles = css`@layer{
/** @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.
 */

:host {
  display: block;
}

.map-layer-picker-container {
  width: 100%;
  align-items: center;
}

.map-layer-picker {
  position: relative;
  width: 100%;
  display: inline-block;
}

.padding-bottom-1 {
  padding-bottom: 1rem;
}

.layer-picker-dropdown {
  height: 100%;
  width: 100%;
}

.max-width-350 {
  max-width: 350px;
}

.height-100 {
  height: 100%;
}

.disabled {
  cursor: default !important;
  user-select: none;
  opacity: var(--calcite-opacity-disabled);
  pointer-events: none;
}

.no-bottom-margin {
  --calcite-label-margin-bottom: 0px;
}

.layer-picker-label-container {
  align-items: center;
  display: inline-flex;
  height: 100%;
  padding-inline-start: 1rem;
  padding-inline-end: 1rem;
}

.padding-start-1 {
  padding-inline-start: 1rem;
}

.cursor-default {
  cursor: default;
}

.popover-list {
  overflow: auto;
  width: 250px;
}
}`;
class MapLayerPicker extends LitElement {
  constructor() {
    super();
    this.appearance = "transparent";
    this.configLayerOrderDefined = false;
    this.defaultLayerId = "";
    this.display = "inline-block";
    this.enabledLayerIds = [];
    this.isMobile = false;
    this.showOnlyUpdatableLayers = false;
    this.selectedIds = [];
    this.scale = "m";
    this.showTables = false;
    this.showTablesDisabled = false;
    this.showSingleLayerAsLabel = false;
    this.type = "select";
    this.showLayersListInPopover = false;
    this.referenceElement = "";
    this.force = false;
    this._hasMultipleLayers = true;
    this._hasValidLayers = true;
    this._isDropdownOpen = false;
    this.ids = [];
    this.selectedName = "";
    this._translations = useT9n({ name: "map-layer-picker", blocking: true });
    this.defaultLayerHonored = false;
    this._layerSelectElement = createRef();
    this._layerComboboxElement = createRef();
    this._pnContextConsumer = useContextConsumer({
      context: pnContext,
      subscribe: true
    });
    this._skipEditCheck = false;
    this._popover = createRef();
    this.beforeLayerSelectionChange = createEvent();
    this.idsFound = createEvent();
    this.noLayersFound = createEvent();
    this.layerSelectionChange = createEvent();
    this.listenOn(window, "mapChanged", this.mapChanged);
  }
  static {
    this.properties = { appearance: 1, configLayerOrderDefined: [5, {}, { type: Boolean }], defaultLayerId: 1, display: 1, enabledLayerIds: [0, {}, { attribute: false }], height: [9, {}, { type: Number }], isMobile: [5, {}, { type: Boolean }], mapView: [0, {}, { attribute: false }], showOnlyUpdatableLayers: [5, {}, { type: Boolean }], placeholderIcon: 1, selectedIds: [0, {}, { attribute: false }], scale: 1, showTables: [5, {}, { type: Boolean }], showTablesDisabled: [5, {}, { type: Boolean }], showSingleLayerAsLabel: [5, {}, { type: Boolean }], type: 1, showLayersListInPopover: [5, {}, { type: Boolean }], referenceElement: 1, force: [16, {}, { state: true }], _hasMultipleLayers: [16, {}, { state: true }], _hasValidLayers: [16, {}, { state: true }], _isDropdownOpen: [16, {}, { state: true }], ids: [16, {}, { state: true }], selectedName: [16, {}, { state: true }], _translations: [16, {}, { state: true }] };
  }
  static {
    this.styles = styles;
  }
  static {
    this.shadowRootOptions = noShadowRoot;
  }
  willUpdate(changes) {
    if (changes.has("mapView") && this.hasUpdated) {
      void this.mapViewWatchHandler();
    }
    if (changes.has("type")) {
      this._layerElement = this.type === "select" ? this._layerSelectElement : this._layerComboboxElement;
    }
    if (changes.has("selectedIds") && this.hasUpdated) {
      if (this.mapView) {
        void (async () => {
          const layer = await getLayerOrTable(this.mapView, this.selectedIds[0]);
          this.selectedName = layer?.title ?? "";
        })();
      }
    }
    if (changes.has("enabledLayerIds") && this.hasUpdated) {
      void this.enabledLayerIdsWatchHandler();
    }
  }
  async enabledLayerIdsWatchHandler() {
    const selectedLayerRemoved = this.selectedIds.length > 0 && !this.enabledLayerIds.includes(this.selectedIds[0]);
    const newLayerAdded = this.enabledLayerIds.some((id) => !this.ids.includes(id));
    const hasOrderChanged = this.ids.toString() !== this.enabledLayerIds.toString();
    if (selectedLayerRemoved) {
      void this.mapViewWatchHandler();
    } else if (newLayerAdded || hasOrderChanged) {
      void this._setLayers();
    }
    this._hasMultipleLayers = this.enabledLayerIds.length > 1;
  }
  async mapViewWatchHandler() {
    await this._setLayers();
    if (this.ids?.length > 0) {
      this._hasValidLayers = true;
      this._hasMultipleLayers = this.ids.length > 1;
      let id = this.ids[0];
      if (this.defaultLayerId && !this.defaultLayerHonored) {
        id = this.defaultLayerId;
      }
      await this._setSelectedLayer(id);
    } else if (this.mapView) {
      this._hasValidLayers = false;
      this.noLayersFound.emit();
    }
  }
  async setLayerById(id, skipEditCheck = false) {
    this._skipEditCheck = skipEditCheck;
    if (!skipEditCheck || skipEditCheck && id !== this.selectedIds[0]) {
      this._setSelectedLayer(id);
    } else if (skipEditCheck && id === this.selectedIds[0]) {
      this.force = true;
      setTimeout(() => {
        this.force = false;
      }, 10);
    }
    this._skipEditCheck = false;
  }
  async setLayerByIds(ids, skipEditCheck = false) {
    this._skipEditCheck = skipEditCheck;
    this._layerSelectionChange(ids);
    this._skipEditCheck = false;
  }
  async updateLayer() {
    await this._setSelectedLayer(this.ids[0]);
  }
  async mapChanged(_evt) {
    const isValid = _evt.detail.isValid;
    if (!isValid) {
      this._hasValidLayers = false;
      this.noLayersFound.emit();
    }
  }
  async load() {
    await this._setLayers();
    if (this.ids?.length > 0) {
      this._hasValidLayers = true;
      this._hasMultipleLayers = this.ids.length > 1;
      if (!this.defaultLayerId) {
        await this._setSelectedLayer(this.ids[0]);
      }
    } else if (this.mapView) {
      this._hasValidLayers = false;
      this.noLayersFound.emit();
    }
  }
  render() {
    const id = "map-layer-picker";
    let style = this.height && this.height > 0 && !this.showLayersListInPopover ? { height: `${this.height.toString()}px` } : {};
    style = { ...style, display: this.display };
    return html`<div class="map-layer-picker-container" style=${safeStyleMap(style)}><div class="map-layer-picker" style=${safeStyleMap(style)}>${!this._hasValidLayers ? this._getInvalidPlaceholder() : !this._hasMultipleLayers && this.showSingleLayerAsLabel ? this._getSingleLayerPlaceholder() : this.type === "combobox" ? this._getCombobox(id) : this.type === "select" ? this._getSelect(id) : this.showLayersListInPopover ? this._getMapLayerPopOver() : this._getDropdown(id)}</div></div>`;
  }
  loaded() {
    if (this.ids?.length > 0 || this.selectedIds?.length === 1) {
      const id = this.selectedIds.length === 1 ? this.selectedIds[0] : this.ids[0];
      if (this.type === "select") {
        if (this._layerElement.value) {
          this._layerElement.value.value = id;
        }
      } else if (this.type === "dropdown") {
        this.selectedName = this._layerNameHash && Object.keys(this._layerNameHash).indexOf(id) > -1 ? this._layerNameHash[id].name : this._tableNameHash && Object.keys(this._tableNameHash).indexOf(id) > -1 ? this._tableNameHash[id].name : "";
      }
    }
    this._popover.value?.addEventListener("calcitePopoverOpen", () => {
      const selected = this.el.querySelector("calcite-dropdown-item[selected]");
      void selected?.setFocus();
    });
  }
  _getMapLayerPopOver() {
    const style = this.height && this.height > 0 ? { "max-height": `${this.height.toString()}px` } : {};
    return html`<calcite-popover auto-close focus-trap-disabled .label=${this.referenceElement} placement=left .referenceElement=${this.referenceElement} scale=s ${ref(this._popover)}><div class=popover-list style=${safeStyleMap(style)}>${this._getMapLayerOptions()}</div></calcite-popover>`;
  }
  _getInvalidPlaceholder() {
    return html`<div><calcite-notice class="height-100" icon=exclamation-mark-triangle id=no-valid-layers kind=danger open><div slot=message>${this._translations.noLayersFound}</div></calcite-notice><calcite-tooltip .label=${this._translations.enableEditUpdate} placement=bottom reference-element=no-valid-layers><span>${this._translations.enableEditUpdate}</span></calcite-tooltip></div>`;
  }
  _getSingleLayerPlaceholder() {
    const itemTypeIcon = this._getItemTypeIcon();
    return html`<div class="layer-picker-label-container cursor-default"><calcite-icon .icon=${itemTypeIcon} scale=s></calcite-icon><calcite-label class="no-bottom-margin padding-start-1">${this.selectedName}</calcite-label></div>`;
  }
  _getSelect(id) {
    return html`<calcite-select id=${id ?? nothing} label @calciteSelectChange=${() => this._layerSelectionChange()} .scale=${this.scale} ${ref(this._layerElement)}>${this._getMapLayerOptions()}</calcite-select>`;
  }
  _getCombobox(id) {
    return html`<calcite-combobox clear-disabled id=${id ?? nothing} label @calciteComboboxChange=${() => this._layerSelectionChange()} .placeholderIcon=${this.placeholderIcon} .scale=${this.scale} selection-mode=single ${ref(this._layerElement)}>${this._getMapLayerOptions()}</calcite-combobox>`;
  }
  _getDropdown(id) {
    return html`<calcite-dropdown class="layer-picker-dropdown" @calciteDropdownBeforeClose=${() => this._isDropdownOpen = false} @calciteDropdownBeforeOpen=${() => this._isDropdownOpen = true}>${this.isMobile ? this._getDropdownButton() : this._getActionDropdownButton(id)}<calcite-dropdown-group selection-mode=single>${this._getMapLayerOptions()}</calcite-dropdown-group></calcite-dropdown>`;
  }
  _getActionDropdownButton(id) {
    return html`<calcite-action appearance=solid id=${id ?? nothing} slot=trigger text>${this._getDropdownButton()}</calcite-action>`;
  }
  _getDropdownButton() {
    const itemTypeIcon = this._getItemTypeIcon();
    const buttonClass = this.isMobile ? "" : "max-width-350";
    const buttonSlot = this.isMobile ? "trigger" : "";
    const buttonIcon = this._isDropdownOpen ? "chevron-up" : "chevron-down";
    return html`<calcite-button alignment=icon-end-space-between .appearance=${this.appearance} class=${safeClassMap(buttonClass)} .iconEnd=${buttonIcon} .iconStart=${itemTypeIcon} kind=neutral slot=${buttonSlot ?? nothing} width=full><div>${this.selectedName}</div></calcite-button>`;
  }
  _getItemTypeIcon() {
    const hasId = this.selectedIds.length > 0 && this._layerNameHash;
    const id = hasId ? this.selectedIds[0] : void 0;
    return hasId ? Object.keys(this._layerNameHash).indexOf(id) > -1 ? "layers" : "table" : "layers";
  }
  _getMapLayerOptions() {
    return this.ids.reduce((prev, cur) => {
      if (this._validLayer(cur)) {
        prev.push(this._getItem(cur, "layer"));
      } else if (this._validTable(cur)) {
        prev.push(this._getItem(cur, "table"));
      }
      return prev;
    }, []);
  }
  _getItem(id, itemType) {
    const item = itemType === "layer" && this._layerNameHash ? this._layerNameHash[id] : this._tableNameHash ? this._tableNameHash[id] : void 0;
    const disabled = this.showOnlyUpdatableLayers ? item && !item.supportsUpdate : false;
    const name = item?.name || "";
    const selected = this.selectedIds.indexOf(id) > -1;
    return this.type === "combobox" ? html`<calcite-combobox-item .disabled=${disabled} .heading=${name} .selected=${selected} .value=${id}></calcite-combobox-item>` : this.type === "select" ? html`<calcite-option .disabled=${disabled} .label=${name} .selected=${selected} .value=${id}></calcite-option>` : this.force && selected || !this.force ? html`<calcite-dropdown-group class=${safeClassMap(disabled ? "disabled" : "")} id=${name ?? nothing} .selectionMode=${disabled ? "none" : "single"}><calcite-dropdown-item .disabled=${itemType === "table" && this.showTablesDisabled ? true : false} .iconStart=${itemType} @click=${disabled ? void 0 : () => void this._setSelectedLayer(id)} .selected=${selected}>${name}</calcite-dropdown-item></calcite-dropdown-group>` : null;
  }
  async _setSelectedLayer(id) {
    if (id !== this.selectedIds[0]) {
      let item;
      const hasDefaultLayer = this.defaultLayerId && !this.defaultLayerHonored;
      if (hasDefaultLayer) {
        item = this._getLayerFromHash(this.defaultLayerId);
        this.defaultLayerHonored = item !== void 0;
        id = this.defaultLayerHonored ? this.defaultLayerId : id;
      }
      item = item ? item : this._getLayerFromHash(id);
      if (!this._skipEditCheck) {
        const _evt = this.beforeLayerSelectionChange.emit({
          currentId: this.selectedIds[0],
          newId: id,
          ref: this.el
        });
        if (_evt.defaultPrevented) {
          return;
        }
      }
      this.selectedName = item?.name;
      this.selectedIds = [id];
      if (this._popover.value) {
        this._popover.value.open = false;
      }
      this.layerSelectionChange.emit(this.selectedIds);
    } else {
      const layer = this.mapView && await getLayerOrTable(this.mapView, this.selectedIds[0]);
      this.selectedName = layer?.title || "";
    }
  }
  _getLayerFromHash(id) {
    return this._layerNameHash && Object.keys(this._layerNameHash).indexOf(id) > -1 ? this._layerNameHash[id] : this._tableNameHash && Object.keys(this._tableNameHash).indexOf(id) > -1 ? this._tableNameHash[id] : void 0;
  }
  async _setLayers() {
    if (this.mapView) {
      await this._initLayerTableHash();
      let layerIds = [];
      if (this._layerNameHash) {
        layerIds = this.showOnlyUpdatableLayers ? this._getEditableIds(this._layerNameHash) : Object.keys(this._layerNameHash);
      }
      let tableIds = [];
      if (this._tableNameHash) {
        tableIds = this.showTables ? this.showOnlyUpdatableLayers ? this._getEditableIds(this._tableNameHash) : Object.keys(this._tableNameHash) : [];
      }
      if (this.configLayerOrderDefined) {
        const allIds = [...layerIds.reverse(), ...tableIds.reverse()];
        this.ids = this.enabledLayerIds.length > 0 ? this.enabledLayerIds.filter((id) => allIds.includes(id)) : allIds;
      } else {
        this.ids = [
          ...layerIds.reverse().filter((n) => this.enabledLayerIds?.length > 0 ? this.enabledLayerIds.indexOf(n) > -1 : true),
          ...tableIds.reverse().filter((n) => this.enabledLayerIds?.length > 0 ? this.enabledLayerIds.indexOf(n) > -1 : true)
        ];
      }
      this.idsFound.emit(this.ids);
    }
  }
  _getEditableIds(hash) {
    return Object.keys(hash).filter((i) => hash[i].supportsUpdate);
  }
  async _initLayerTableHash() {
    this._layerNameHash = this.mapView && await getMapLayerHash(this.mapView, this.showOnlyUpdatableLayers);
    this._tableNameHash = this.showTables && this.mapView ? await getMapTableHash(this.mapView, this.showOnlyUpdatableLayers) : {};
  }
  _validLayer(id) {
    const _state = this._pnContextConsumer.value;
    const name = this._layerNameHash && this._layerNameHash[id]?.name;
    return name !== void 0 && Object.keys(_state?.managedLayers || []).indexOf(name) < 0 && (this.enabledLayerIds?.length > 0 ? this.enabledLayerIds.indexOf(id) > -1 : true);
  }
  _validTable(id) {
    const _state = this._pnContextConsumer.value;
    const name = this._tableNameHash && this._tableNameHash[id]?.name;
    const validName = name && this.showTables;
    return validName ? (_state?.managedTables || []).indexOf(name) < 0 && (this.enabledLayerIds?.length > 0 ? this.enabledLayerIds.indexOf(id) > -1 : true) : validName !== void 0;
  }
  _layerSelectionChange(ids) {
    if (this._layerElement.value) {
      const _ids = ids ? ids : Array.isArray(this._layerElement.value.value) ? this._layerElement.value.value : [this._layerElement.value.value];
      if (JSON.stringify(_ids) !== JSON.stringify([""])) {
        if (!this._skipEditCheck) {
          const _evt = this.beforeLayerSelectionChange.emit({
            currentIds: this.selectedIds,
            newIds: _ids,
            ref: this.el
          });
          if (_evt.defaultPrevented) {
            return;
          }
        }
        this.selectedIds = _ids;
        this.layerSelectionChange.emit(this.selectedIds);
      }
    }
  }
}
customElement("map-layer-picker", MapLayerPicker);
export {
  MapLayerPicker
};
