/// <reference path="../../index.d.ts" />
import type MapView from "@arcgis/core/views/MapView.js";
import type SceneView from "@arcgis/core/views/SceneView.js";
import type TemplateListItem from "@arcgis/core/editing/templates/TemplateListItem.js";
import type SubtypeGroupLayer from "@arcgis/core/layers/SubtypeGroupLayer.js";
import type { PublicLitElement as LitElement } from "@arcgis/lumina";
import type { ArcgisReferenceElement } from "../types.js";
import type { LayerWithFeatureTemplatesUnion } from "@arcgis/core/layers/types.js";
import type { T9nMeta } from "@arcgis/lumina/controllers";

/**
 * The FeatureTemplates component is part of an editing workflow. Its main purpose is to display [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) templates from one or more feature layers.
 *
 * @since 5.1
 * @internal
 */
export abstract class ArcgisFeatureTemplates extends LitElement {
  /** @internal */
  protected _messages: Partial<{
      componentLabel: string;
      templates: string;
      recent: string;
      favorites: string;
      updating: string;
      point: string;
      multipoint: string;
      polyline: string;
      polygon: string;
      extent: string;
      mesh: string;
      filterPlaceholder: string;
      noneSpecified: string;
      removeFavorite: string;
      removeRecent: string;
      addFavorite: string;
      noFavorites: string;
      noTemplates: string;
      noRecent: string;
      noMatchingTemplates: string;
  }> & T9nMeta<{
      componentLabel: string;
      templates: string;
      recent: string;
      favorites: string;
      updating: string;
      point: string;
      multipoint: string;
      polyline: string;
      polygon: string;
      extent: string;
      mesh: string;
      filterPlaceholder: string;
      noneSpecified: string;
      removeFavorite: string;
      removeRecent: string;
      addFavorite: string;
      noFavorites: string;
      noTemplates: string;
      noRecent: string;
      noMatchingTemplates: string;
  }>;
  /** Provide a function to dynamically enable or disable templates in the component. */
  accessor applicationDisabledFunction: ((template: TemplateListItem) => boolean) | undefined;
  /** Provide a function to dynamically hide/remove templates from the component. */
  accessor applicationFilterFunction: ((template: TemplateListItem) => boolean) | undefined;
  /** Provide a list of sections and templates. If not supplied, the component will load the templates from the layers in the view. */
  accessor applicationTemplates: Array<ITemplateSection> | undefined;
  /**
   * If true, the component will not be destroyed automatically when it is
   * disconnected from the document. This is useful when you want to move the
   * component to a different place on the page, or temporarily hide it. If this
   * is set, make sure to call the [destroy()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-feature-templates/#destroy) method when you are done to
   * prevent memory leaks.
   *
   * @default false
   */
  accessor autoDestroyDisabled: boolean;
  /**
   * When true, the component is visually withdrawn and cannot receive user interaction.
   *
   * @default false
   */
  accessor disabled: boolean;
  /**
   * Decide if templates should be disabled when the layer is not visible, or not visible at the current scale.
   *
   * @default "never"
   */
  accessor disableTemplatesMode: "never" | "scale" | "visible";
  /**
   * Determine if templates should be shown grouped, or in a single flat list
   *
   * @default "grouped"
   */
  accessor display: "flat" | "grouped";
  /** The list of templates in the component */
  get effectiveTemplates(): Array<ITemplateSection>;
  /**
   * Determines if feature templates for tables should be shown
   *
   * @default false
   */
  accessor excludeTables: boolean;
  /**
   * The list of templates in the component
   *
   * @interface
   */
  get favorites(): Set<string>;
  /**
   * Include a favorites used tab
   *
   * @default false
   * @internal
   */
  accessor favoritesEnabled: boolean;
  /**
   * The text the user has entered to filter the list on the favorites tab
   *
   * @default ""
   * @internal
   */
  accessor favoritesFilterText: string;
  /**
   * The text the user has entered to filter the list
   *
   * @default ""
   */
  accessor filterText: string;
  /**
   * When templates are grouped, determine the group by policy. Note: if the component has been supplied with applicationTemplates, the templates will keep the supplied groupings.
   *
   * @default "layer"
   */
  accessor groupBy: "geometry" | "layer";
  /** If a group by function is supplied, then the templates will be grouped by this function. */
  accessor groupByFunction: ((template: TemplateListItem) => string) | undefined;
  /**
   * Determine if the template description should be displayed
   *
   * @default false
   */
  accessor hideTemplateDescription: boolean;
  /**
   * Decide if templates should be hidden when the layer is not visible, or not visible at the current scale.
   *
   * @default "never"
   */
  accessor hideTemplatesMode: "never" | "scale" | "visible";
  /** List of layers for which to show Templates. If not provided, the layers will be derived from the View. */
  accessor layers: (LayerWithFeatureTemplatesUnion | SubtypeGroupLayer)[] | undefined;
  /**
   * The text the user has entered to filter the list on the recent tab
   *
   * @default ""
   * @internal
   */
  accessor recentFilterText: string;
  /**
   * The list of recently used template ids.
   *
   * @interface
   */
  get recentlyUsed(): Array<string>;
  /**
   * Include a recently used tab
   *
   * @default false
   * @internal
   */
  accessor recentlyUsedEnabled: boolean;
  /**
   * By assigning the `id` attribute of the Map or Scene component to this property, you can position a child component anywhere in the DOM while still maintaining a connection to the Map or Scene.
   *
   * @see [Associate components with a Map or Scene component](https://developers.arcgis.com/javascript/latest/programming-patterns/#associate-components-with-a-map-or-scene-component)
   */
  accessor referenceElement: ArcgisReferenceElement | string | undefined;
  /**
   * Function which restores the list of favorites from a previous session
   *
   * @internal
   */
  accessor restoreFavorites: (() => Promise<Array<string>>) | undefined;
  /**
   * Function which restores the list of recently used templates from a previous session
   *
   * @internal
   */
  accessor restoreRecentlyUsed: (() => Promise<Array<string>>) | undefined;
  /**
   * When templates are grouped, determine how the groups are sorted. If the component has been supplied with a sectionSortByFunction then this will be used instead.
   *
   * @default "system"
   */
  accessor sectionSortBy: "alphabetical" | "system";
  /** If provided, this function can be used to re-order the sections. */
  accessor sectionSortByFunction: ((sections: ITemplateSection[]) => ITemplateSection[]) | undefined;
  /** Currently selected template */
  get selectedTemplate(): TemplateListItem | undefined;
  /** Currently selected template id */
  accessor selectedTemplateId: string | undefined;
  /**
   * Fetch shared templates, if the layer's in the view have shared Templates.
   *
   * @default false
   * @internal
   */
  accessor sharedTemplatesDisabled: boolean;
  /**
   * Indicates whether to display the collapse button.
   *
   * @default false
   * @since 5.1
   */
  accessor showCollapseButton: boolean;
  /**
   * Indicates whether to show the templates filter
   *
   * @default false
   * @since 5.1
   */
  accessor showFilter: boolean;
  /**
   * Determines how templates are ordered. This will either be in alphabetical order
   * or the order they are defined in the layer schema.
   *
   * @default "alphabetical"
   */
  accessor templateSortBy: "alphabetical" | "system";
  /** If provided, this function can be used to re-order the templates. */
  accessor templateSortByFunction: ((templates: TemplateListItem[]) => TemplateListItem[]) | undefined;
  /**
   * Determine if the templates list is updating.
   *
   * @default false
   */
  get updating(): boolean;
  /**
   * The view associated with the component. 
   *   > **Note:** The recommended approach is to fully migrate applications to use map and scene components and avoid using MapView and SceneView directly. However, if you are migrating a large application from widgets to components, you might prefer a more gradual transition. To support this use case, the SDK includes this `view` property which connects a component to a MapView or SceneView. Ultimately, once migration is complete, the arcgis-feature-templates component will be associated with a map or scene component rather than using the `view` property.
   */
  accessor view: MapView | SceneView | undefined;
  /** Permanently destroy the component */
  destroy(): Promise<void>;
  /** Emitted when the value of a property is changed. Use this to listen to changes to properties. */
  readonly arcgisPropertyChange: import("@arcgis/lumina").TargetedEvent<this, { name: "effectiveTemplates" | "filterText" | "recentlyUsed" | "favorites"; }>;
  /** Emitted when the component associated with a map or scene view is ready to be interacted with. */
  readonly arcgisReady: import("@arcgis/lumina").TargetedEvent<this, void>;
  /** The user has selected a template */
  readonly arcgisSelectTemplate: import("@arcgis/lumina").TargetedEvent<this, { template: TemplateListItem; }>;
  /** The source of templates has changed. */
  readonly arcgisTemplatesChanged: import("@arcgis/lumina").TargetedEvent<this, void>;
  readonly "@eventTypes": {
    arcgisPropertyChange: ArcgisFeatureTemplates["arcgisPropertyChange"]["detail"];
    arcgisReady: ArcgisFeatureTemplates["arcgisReady"]["detail"];
    arcgisSelectTemplate: ArcgisFeatureTemplates["arcgisSelectTemplate"]["detail"];
    arcgisTemplatesChanged: ArcgisFeatureTemplates["arcgisTemplatesChanged"]["detail"];
  };
}

/**
 * Template section
 *
 * @internal
 */
export type ITemplateSection = {
  /** Name of the section */
  sectionName: string;
  /**
   * Whether to translate the section name
   *
   * @internal
   */
  autoTranslate?: boolean;
  /** List of Template items in the section */
  templates: TemplateListItem[];
};