/* COPYRIGHT Esri - https://js.arcgis.com/5.2/LICENSE.txt */
import { c as T } from "../../chunks/runtime.js";
import { css as g, html as o } from "lit";
import { LitElement as b, createEvent as h } from "@arcgis/lumina";
import { u as w } from "../../chunks/useT9n.js";
import { u as F } from "../../chunks/useView.js";
import { m as M } from "../../chunks/useViewModel.js";
import { property as l, subclass as S } from "@arcgis/core/core/accessorSupport/decorators.js";
import _ from "@arcgis/core/core/Accessor.js";
import u from "@arcgis/core/editing/templates/TemplateListItem.js";
import { getAllStandardFeatureTemplatesForLayer as $, getTemplatesForLayers as x } from "@arcgis/core/applications/Components/templateUtils.js";
import { i as y, c as v } from "../../chunks/layer-utils.js";
import { isTable as m, getEffectiveLayerCapabilities as B } from "@arcgis/core/applications/Components/layerUtils.js";
import { usePropertyChange as D } from "@arcgis/lumina/controllers";
import { watch as f } from "@arcgis/core/core/reactiveUtils.js";
import { debounce as L } from "@arcgis/toolkit/function";
const E = g`:host{display:flex;position:relative;background-color:var(--calcite-color-foreground-1);color:var(--calcite-color-text-2);font-size:var(--calcite-font-size);line-height:var(--calcite-font-line-height-relative-tight)}.filter-no-results{padding:var(--calcite-spacing-md) var(--calcite-spacing-lg)}.root{display:flex;flex:1 1 auto;overflow:hidden auto;transition:max-height .25s ease-in-out}.root>*{width:100%;box-sizing:border-box}.feature-template-tabs{--calcite-tab-background-color: transparent}`;
var U = Object.defineProperty, I = Object.getOwnPropertyDescriptor, a = (t, e, i, r) => {
  for (var n = r > 1 ? void 0 : r ? I(e, i) : e, p = t.length - 1, c; p >= 0; p--)
    (c = t[p]) && (n = (r ? c(e, i, n) : c(n)) || n);
  return r && n && U(e, i, n), n;
};
function C(t) {
  switch (t) {
    case "point":
    case "multipoint":
    case "polyline":
    case "polygon":
    case "extent":
    case "mesh":
      return t;
  }
  return "noneSpecified";
}
const R = (t) => C(t.layer.geometryType ?? "");
let s = class extends _ {
  //#region Lifecycle
  constructor(t) {
    super(t), this._hasRunInitialLoad = !1, this.favoritesEnabled = !1, this.recentlyUsedEnabled = !1, this.hideTemplateDescription = !1, this.filterText = "", this.recentFilterText = "", this.favoritesFilterText = "", this.display = "grouped", this.groupBy = "layer", this.hideTemplatesMode = "never", this.disableTemplatesMode = "never", this.sectionSortBy = "system", this.templateSortBy = "alphabetical", this.sharedTemplatesDisabled = !1, this.excludeTables = !1, this.favorites = /* @__PURE__ */ new Set(), this.fetchingTemplateMetaData = !1, this.recentlyUsed = [];
  }
  //#endregion
  //#region Public methods
  /*
   * The template source has changed. This maybe because layers
   * have been added or removed, the map changed or application templates
   * supplied.
   */
  async handleTemplateSourceDefinitionChanged() {
    if (this._hasRunInitialLoad = !1, this.applicationTemplates) {
      await this._restore();
      return;
    }
    try {
      this.fetchingTemplateMetaData = !0;
      const t = this.activeLayers;
      if (await Promise.allSettled(t.map((e) => e.load())), this.sharedTemplatesDisabled) {
        const e = [];
        for (const i of t) {
          const r = $(i);
          r.length > 0 && e.push({
            layer: i,
            templates: r
          });
        }
        this.mapTemplates = e;
        return;
      }
      this.mapTemplates = await x(t, this.view, void 0, {
        returnVisibleTemplatesOnly: !0
      }), await this._restore();
    } catch {
      this.mapTemplates = [];
    } finally {
      this.fetchingTemplateMetaData = !1;
    }
  }
  get loading() {
    return !this._hasRunInitialLoad || this.layers !== void 0 || this.applicationTemplates !== void 0 || !this.view?.ready;
  }
  /*
   * Add a favorite
   */
  async addFavorite(t) {
    this.favorites.add(t.id), this.favorites = new Set(this.favorites);
  }
  /*
   * Remove a favorite
   */
  async removeFavorite(t) {
    this.favorites.delete(t.id), this.favorites = new Set(this.favorites);
  }
  /*
   * Add a recently selected Template
   */
  addRecent(t) {
    if (!this.recentlyUsedEnabled)
      return;
    const e = this.recentlyUsed.filter((i) => i !== t.id);
    e.unshift(t.id) > 20 && (e.length = 20), this.recentlyUsed = e;
  }
  /*
   * Remove a favorite
   */
  async removeRecent(t) {
    this.recentlyUsed = this.recentlyUsed.filter((e) => e !== t.id);
  }
  //#endregion
  //#region Private methods
  /*
   * Restore favorites and recents, if there is a provider.
   */
  async _restore() {
    try {
      if (this.favoritesEnabled && this.restoreFavorites) {
        const t = await this.restoreFavorites();
        this.favorites = new Set(t ?? []);
      }
    } catch {
    }
    try {
      if (this.recentlyUsedEnabled && this.restoreRecentlyUsed) {
        const t = await this.restoreRecentlyUsed();
        this.recentlyUsed = t ?? [];
      }
    } catch {
    }
  }
  /*
   * Sort the templates based on a function or alphabetical.
   */
  _sortTemplates(t) {
    if (this.templateSortByFunction) {
      const e = this.templateSortByFunction(t) ?? null;
      return e === null ? t : e;
    }
    return this.templateSortBy === "alphabetical" ? t.toSorted((e, i) => e.label.localeCompare(i.label)) : t;
  }
  /*
   * Sort the sections based on a function or alphabetical, and sort the templates within the sections as well.
   */
  _sortSections(t) {
    if (this.sectionSortByFunction) {
      const e = this.sectionSortByFunction(t);
      e && (t = e);
    } else if (this.sectionSortBy === "alphabetical")
      t = t.toSorted((e, i) => e.sectionName.localeCompare(i.sectionName));
    else if (this.groupBy === "geometry" && !this.groupByFunction) {
      const e = {
        point: 1,
        multipoint: 2,
        polyline: 3,
        polygon: 4,
        extent: 5,
        mesh: 6,
        noneSpecified: 7
      };
      t = t.toSorted((i, r) => {
        const n = e[i.sectionName] ?? 10, p = e[r.sectionName] ?? 10;
        return n - p;
      });
    }
    for (const e of t)
      e.templates = this._sortTemplates(e.templates);
    return t;
  }
  _layerIsVisibleAtCurrentScale(t) {
    if (!this.view)
      return !0;
    let e = t;
    y(t) && (e = t.parent);
    const i = this.view.allLayerViews.find((r) => r.layer === e);
    if (!i)
      return !0;
    if (y(t)) {
      const r = this.view.scale;
      if (i.visibleAtCurrentScale) {
        const n = t.minScale, p = t.maxScale;
        let c = !n, d = !p;
        return !c && r <= n && (c = !0), !d && r >= p && (d = !0), c && d;
      }
    }
    return i.visibleAtCurrentScale;
  }
  get activeLayers() {
    const t = [];
    for (const e of this.layers ?? [])
      if (v(e))
        for (const i of e.sublayers)
          t.push(i);
      else
        t.push(e);
    if (this.layers === void 0 || this.layers === null) {
      for (const e of [
        ...this.view?.map?.allLayers?.slice(0).reverse() ?? [],
        ...this.excludeTables ? [] : this.view?.map?.allTables?.slice(0).reverse() ?? []
      ])
        if (e.type === "feature" || e.type === "scene" || e.type === "geojson" || e.type === "oriented-imagery" || e.type === "knowledge-graph")
          t.push(e);
        else if (v(e))
          for (const i of e.sublayers)
            t.push(i);
    }
    return t;
  }
  get selectedTemplate() {
    return this.allTemplates.find((t) => t.id === this.selectedTemplateId);
  }
  get effectiveTemplates() {
    return this.templates.map((t) => ({ ...t, templates: t.templates.filter((e) => this.inclusionFilter(e)) })).filter((t) => t.templates.length > 0);
  }
  get templateList() {
    return this._sortTemplates(this.effectiveTemplates.flatMap((t) => t.templates));
  }
  get allTemplates() {
    return this._sortTemplates(this.templates.flatMap((t) => t.templates));
  }
  inclusionFilter(t) {
    if (this.excludeTables && m(t.layer) || this.applicationFilterFunction?.(t) === !1)
      return !1;
    const e = B(t.layer)?.operations;
    return e?.supportsEditing === !1 && !e?.supportsAdd ? !1 : m(t.layer) ? !0 : !(this.hideTemplatesMode === "visible" && !t.layer.visible || this.hideTemplatesMode === "scale" && !this._layerIsVisibleAtCurrentScale(t.layer));
  }
  get templateSetKey() {
    return this._sortTemplates(this.allTemplates).map((t) => t.id).join(",");
  }
  get disabledTemplates() {
    const t = /* @__PURE__ */ new Set();
    for (const e of this.allTemplates) {
      if (this.applicationDisabledFunction && this.applicationDisabledFunction(e)) {
        t.add(e);
        continue;
      }
      if (!m(e.layer)) {
        if (this.disableTemplatesMode === "visible" && !e.layer.visible) {
          t.add(e);
          continue;
        }
        if (this.disableTemplatesMode === "scale" && this.view && !this._layerIsVisibleAtCurrentScale(e.layer)) {
          t.add(e);
          continue;
        }
      }
    }
    return t;
  }
  get templates() {
    return this.applicationTemplates ?? this.organizedMapTemplates;
  }
  get organizedMapTemplates() {
    if (this.groupByFunction || this.groupBy === "geometry") {
      const t = !this.groupByFunction, e = this.groupByFunction ?? R, i = /* @__PURE__ */ new Map();
      for (const r of this.mapTemplates ?? [])
        for (const n of r.templates) {
          const p = new u({ template: n, layer: r.layer }), c = e(p);
          if (c != null)
            if (i.has(c))
              i.get(c)?.templates.push(p);
            else {
              const d = {
                sectionName: c,
                ...t ? { autoTranslate: !0 } : {},
                templates: [p]
              };
              i.set(c, d);
            }
        }
      return this._sortSections(Array.from(i.values()));
    }
    return this._sortSections(
      (this.mapTemplates ?? []).map(({ layer: t, templates: e }) => ({
        sectionName: t.title ?? "",
        templates: e.map((i) => new u({ layer: t, template: i }))
      })).filter((t) => t.templates.length > 0)
    );
  }
  get updating() {
    return this.fetchingTemplateMetaData;
  }
  get favoriteTemplates() {
    const t = [];
    for (const e of this.effectiveTemplates)
      for (const i of e.templates)
        this.favorites.has(i.id) && t.push(i);
    return t;
  }
  get recentTemplates() {
    const t = /* @__PURE__ */ new Map();
    for (const i of this.effectiveTemplates)
      for (const r of i.templates)
        t.set(r.id, r);
    const e = [];
    for (const i of this.recentlyUsed)
      t.has(i) && e.push(t.get(i));
    return e;
  }
  //#endregion
};
a([
  l()
], s.prototype, "loading", 1);
a([
  l()
], s.prototype, "_hasRunInitialLoad", 2);
a([
  l()
], s.prototype, "activeLayers", 1);
a([
  l()
], s.prototype, "favoritesEnabled", 2);
a([
  l()
], s.prototype, "recentlyUsedEnabled", 2);
a([
  l()
], s.prototype, "hideTemplateDescription", 2);
a([
  l()
], s.prototype, "filterText", 2);
a([
  l()
], s.prototype, "recentFilterText", 2);
a([
  l()
], s.prototype, "favoritesFilterText", 2);
a([
  l()
], s.prototype, "selectedTemplateId", 2);
a([
  l()
], s.prototype, "selectedTemplate", 1);
a([
  l()
], s.prototype, "layers", 2);
a([
  l()
], s.prototype, "restoreFavorites", 2);
a([
  l()
], s.prototype, "restoreRecentlyUsed", 2);
a([
  l()
], s.prototype, "applicationDisabledFunction", 2);
a([
  l()
], s.prototype, "applicationFilterFunction", 2);
a([
  l()
], s.prototype, "display", 2);
a([
  l()
], s.prototype, "groupBy", 2);
a([
  l()
], s.prototype, "hideTemplatesMode", 2);
a([
  l()
], s.prototype, "disableTemplatesMode", 2);
a([
  l()
], s.prototype, "groupByFunction", 2);
a([
  l()
], s.prototype, "sectionSortBy", 2);
a([
  l()
], s.prototype, "templateSortBy", 2);
a([
  l()
], s.prototype, "sectionSortByFunction", 2);
a([
  l()
], s.prototype, "templateSortByFunction", 2);
a([
  l()
], s.prototype, "sharedTemplatesDisabled", 2);
a([
  l()
], s.prototype, "excludeTables", 2);
a([
  l()
], s.prototype, "favorites", 2);
a([
  l()
], s.prototype, "effectiveTemplates", 1);
a([
  l()
], s.prototype, "templateList", 1);
a([
  l()
], s.prototype, "allTemplates", 1);
a([
  l()
], s.prototype, "templateSetKey", 1);
a([
  l()
], s.prototype, "disabledTemplates", 1);
a([
  l()
], s.prototype, "templates", 1);
a([
  l()
], s.prototype, "mapTemplates", 2);
a([
  l()
], s.prototype, "organizedMapTemplates", 1);
a([
  l()
], s.prototype, "fetchingTemplateMetaData", 2);
a([
  l()
], s.prototype, "updating", 1);
a([
  l()
], s.prototype, "applicationTemplates", 2);
a([
  l()
], s.prototype, "favoriteTemplates", 1);
a([
  l()
], s.prototype, "recentTemplates", 1);
a([
  l()
], s.prototype, "recentlyUsed", 2);
a([
  l()
], s.prototype, "view", 2);
s = a([
  S("components.feature-templates.FeatureTemplatesViewModel")
], s);
const A = M(s);
class P extends b {
  constructor() {
    super(...arguments), this._messages = w(), this.viewModel = A(this), this.favoritesEnabled = this.viewModel.favoritesEnabled, this.favorites = this.viewModel.favorites, this.restoreFavorites = this.viewModel.restoreFavorites, this.restoreRecentlyUsed = this.viewModel.restoreRecentlyUsed, this.recentlyUsed = this.viewModel.recentlyUsed, this.sharedTemplatesDisabled = this.viewModel.sharedTemplatesDisabled, this.filterText = this.viewModel.filterText, this.recentFilterText = this.viewModel.recentFilterText, this.favoritesFilterText = this.viewModel.favoritesFilterText, this.recentlyUsedEnabled = this.viewModel.recentlyUsedEnabled, this.excludeTables = this.viewModel.excludeTables, this.effectiveTemplates = this.viewModel.effectiveTemplates, this.applicationTemplates = this.viewModel.applicationTemplates, this.selectedTemplateId = this.viewModel.selectedTemplateId, this.selectedTemplate = this.viewModel.selectedTemplate, this.applicationFilterFunction = this.viewModel.applicationFilterFunction, this.applicationDisabledFunction = this.viewModel.applicationDisabledFunction, this.display = this.viewModel.display, this.groupBy = this.viewModel.groupBy, this.sectionSortBy = this.viewModel.sectionSortBy, this.templateSortBy = this.viewModel.templateSortBy, this.templateSortByFunction = this.viewModel.templateSortByFunction, this.sectionSortByFunction = this.viewModel.sectionSortByFunction, this.hideTemplatesMode = this.viewModel.hideTemplatesMode, this.disableTemplatesMode = this.viewModel.disableTemplatesMode, this.groupByFunction = this.viewModel.groupByFunction, this.hideTemplateDescription = this.viewModel.hideTemplateDescription, this.layers = this.viewModel.layers, this.view = F(this), this.autoDestroyDisabled = !1, this.updating = this.viewModel.updating, this.disabled = !1, this.showCollapseButton = !1, this.showFilter = !1, this.arcgisPropertyChange = D()("effectiveTemplates", "filterText", "recentlyUsed", "favorites"), this.arcgisReady = h(), this.arcgisTemplatesChanged = h(), this.arcgisSelectTemplate = h();
  }
  static {
    this.properties = { favoritesEnabled: 5, favorites: 32, restoreFavorites: 0, restoreRecentlyUsed: 0, recentlyUsed: 32, sharedTemplatesDisabled: 5, filterText: 1, recentFilterText: 1, favoritesFilterText: 1, recentlyUsedEnabled: 5, excludeTables: 5, effectiveTemplates: 32, applicationTemplates: 0, selectedTemplateId: 1, selectedTemplate: 32, applicationFilterFunction: 0, applicationDisabledFunction: 0, display: 1, groupBy: 1, sectionSortBy: 1, templateSortBy: 1, templateSortByFunction: 0, sectionSortByFunction: 0, hideTemplatesMode: 1, disableTemplatesMode: 1, groupByFunction: 0, hideTemplateDescription: 5, layers: 0, view: 0, referenceElement: 1, autoDestroyDisabled: 5, updating: 32, disabled: 5, showCollapseButton: 5, showFilter: 5 };
  }
  static {
    this.styles = E;
  }
  async destroy() {
    await this.manager.destroy();
  }
  loaded() {
    this.manager.onLifecycle(() => [
      // Ensure the view is always mapped to the viewmodel
      f(() => this.view, () => {
        this.viewModel.view = this.view;
      }, { initial: !0 }),
      f(() => this.viewModel.templateSetKey, () => {
        this.arcgisTemplatesChanged.emit();
      }),
      // Watch if the list of active layers changes. This will trigger a reload
      f(() => [
        this.viewModel.activeLayers?.map((e) => e.id).join(","),
        this.viewModel?.applicationTemplates,
        this.viewModel?.sharedTemplatesDisabled
      ], L(() => (
        // Trigger refetching of templates
        this.viewModel.handleTemplateSourceDefinitionChanged()
      ), 10), { initial: !0 })
    ]);
  }
  _handleSelectTemplate(e) {
    this.selectedTemplateId = e.id, this.arcgisSelectTemplate.emit({ template: e }), this.viewModel.addRecent(e);
  }
  _removeTemplateFromList(e, i) {
    if (i === "favorites") {
      this.viewModel.removeFavorite(e);
      return;
    }
    this.viewModel.removeRecent(e);
  }
  _renderTemplates() {
    return this.effectiveTemplates.length === 0 ? o`<calcite-notice icon=list open class="filter-no-results"><div slot=message>${this._messages.noTemplates}</div></calcite-notice>` : o`<calcite-list .filterPlaceholder=${this._messages.filterPlaceholder ?? ""} .filterText=${this.filterText} .label=${this._messages?.templates ?? ""} .filterEnabled=${this.showFilter} selection-appearance=border selection-mode=single @calciteListFilter=${(e) => {
      this.filterText = e.target.filterText;
    }}>${this.display === "grouped" ? this.effectiveTemplates.map((e) => o`<calcite-list-item-group .heading=${e.autoTranslate ? this._messages[e.sectionName] ?? "" : e.sectionName}>${e.templates.map((i) => o`<calcite-list-item .disabled=${this.viewModel.disabledTemplates.has(i)} .label=${i.label} .selected=${i.id === this.selectedTemplateId} .description=${this.hideTemplateDescription ? void 0 : i.description} .value=${i.id} @calciteListItemSelect=${() => {
      this._handleSelectTemplate(i);
    }}><arcgis-template-image slot=content-start .template=${i}></arcgis-template-image>${this._renderAddFavorite(i)}</calcite-list-item>`)}</calcite-list-item-group>`) : this.viewModel.templateList.map((e) => o`<calcite-list-item .disabled=${this.viewModel.disabledTemplates.has(e)} .label=${e.label} .selected=${e.id === this.selectedTemplateId} .description=${this.hideTemplateDescription ? void 0 : e.description} .value=${e.id} @calciteListItemSelect=${() => {
      this._handleSelectTemplate(e);
    }}><arcgis-template-image slot=content-start .template=${e}></arcgis-template-image>${this._renderAddFavorite(e)}</calcite-list-item>`)}${this._renderFilteredEmpty()}</calcite-list>`;
  }
  _renderAddFavorite(e) {
    return this.viewModel.favoritesEnabled ? o`<calcite-action slot=actions-end .icon=${this.viewModel.favorites.has(e.id) ? "heart-f" : "heart"} @click=${() => {
      this.viewModel.favorites.has(e.id) ? this.viewModel.removeFavorite(e) : this.viewModel.addFavorite(e);
    }} .text=${this._messages.addFavorite ?? ""}></calcite-action>` : "";
  }
  _renderList(e) {
    const i = e === "favorites" ? this.viewModel.favoriteTemplates : this.viewModel.recentTemplates;
    return i.length === 0 ? o`<calcite-notice icon=list open class="filter-no-results"><div slot=message>${e === "favorites" ? this._messages.noFavorites : this._messages.noRecent}</div></calcite-notice>` : o`<calcite-list .filterText=${e === "favorites" ? this.favoritesFilterText : this.recentFilterText} .filterPlaceholder=${this._messages.filterPlaceholder ?? ""} .label=${(e === "favorites" ? this._messages.favorites : this._messages.recent) ?? ""} .filterEnabled=${this.showFilter} selection-appearance=border selection-mode=single @calciteListFilter=${(r) => {
      this.filterText = r.target.filterText;
    }}>${i.map((r) => o`<calcite-list-item .disabled=${this.viewModel.disabledTemplates.has(r)} .label=${r.label} .description=${this.hideTemplateDescription ? void 0 : r.description} .value=${r.id} @calciteListItemSelect=${() => {
      this._handleSelectTemplate(r);
    }}><arcgis-template-image slot=content-start .template=${r}></arcgis-template-image><calcite-action slot=actions-end icon=x @click=${() => {
      this._removeTemplateFromList(r, e);
    }} .text=${(e === "favorites" ? this._messages.removeFavorite : this._messages.removeRecent) ?? ""}></calcite-action></calcite-list-item>`)}${this._renderFilteredEmpty()}</calcite-list>`;
  }
  _renderFilteredEmpty() {
    return o`<calcite-notice icon=filter slot=filter-no-results open class="filter-no-results"><div slot=message>${this._messages.noMatchingTemplates}</div></calcite-notice>`;
  }
  _renderContent() {
    return this.effectiveTemplates.length === 0 && this.viewModel.loading ? null : this.favoritesEnabled || this.recentlyUsedEnabled ? o`<calcite-tabs class="feature-template-tabs"><calcite-tab-nav slot=title-group><calcite-tab-title icon-start=templates selected>${this._messages.templates}</calcite-tab-title>${this.recentlyUsedEnabled ? o`<calcite-tab-title icon-start=clock>${this._messages.recent}</calcite-tab-title>` : ""}${this.favoritesEnabled ? o`<calcite-tab-title icon-start=heart>${this._messages.favorites}</calcite-tab-title>` : ""}</calcite-tab-nav><calcite-tab selected>${this._renderTemplates()}</calcite-tab><calcite-tab>${this._renderList("recent")}</calcite-tab><calcite-tab>${this._renderList("favorites")}</calcite-tab></calcite-tabs>` : this._renderTemplates();
  }
  render() {
    return o`<div class="root">${this._renderContent()}${this.viewModel.updating || this.disabled ? o`<calcite-scrim><calcite-loader scale=s label .hidden=${!this.viewModel.updating}></calcite-loader></calcite-scrim>` : null}</div>`;
  }
}
T("arcgis-feature-templates", P);
export {
  P as ArcgisFeatureTemplates
};
