import type Graphic from "../Graphic.js";
import type EsriMap from "../Map.js";
import type Point from "../geometry/Point.js";
import type SpatialReference from "../geometry/SpatialReference.js";
import type Widget from "./Widget.js";
import type FeatureViewModel from "./Feature/FeatureViewModel.js";
import type { Icon } from "@esri/calcite-components/components/calcite-icon";
import type { SpatialReferenceProperties } from "../geometry/SpatialReference.js";
import type { TimeZone } from "../time/types.js";
import type { MapViewOrSceneView } from "../views/MapViewOrSceneView.js";
import type { WidgetProperties } from "./Widget.js";
import type { FeatureViewModelProperties } from "./Feature/FeatureViewModel.js";
import type { HeadingLevel } from "./support/types.js";
import type { GraphicProperties } from "../Graphic.js";
import type { PointProperties } from "../geometry/Point.js";

export interface FeatureProperties extends WidgetProperties, Partial<Pick<Feature, "defaultPopupTemplateEnabled" | "headingLevel" | "map" | "view" | "visibleElements">> {
  /**
   * The [Graphic](https://developers.arcgis.com/javascript/latest/references/core/Graphic/) used to represent the feature.
   *
   * @see [PopupTemplate.content](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/#content)
   * @example
   * let graphic = new Graphic({
   *   geometry: view.center,
   *   attributes: {
   *     "name": "Spruce",
   *     "family": "Pinaceae",
   *     "count": 126
   *   },
   *   symbol: new SimpleMarkerSymbol({
   *     style: "square",
   *     color: "blue",
   *     size: "8px"
   *   }),
   *   popupTemplate: {
   *     content: [
   *       {
   *         // Set popup template content
   *       }
   *     ]
   *   }
   * });
   */
  graphic?: GraphicProperties | null;
  /**
   * Icon which represents the widget. It is typically used when the widget is controlled by another
   * one (e.g. in the Expand widget).
   *
   * @default "polygon"
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  icon?: Icon["icon"] | null;
  /**
   * The widget's default label.
   *
   * @since 4.11
   */
  label?: string | null;
  /**
   * The location of the graphic to be displayed.
   *
   * @since 4.31
   */
  location?: PointProperties | null;
  /**
   * The spatial reference used for [Arcade](https://developers.arcgis.com/arcade) operations.
   * This property should be set if the Feature widget executes Arcade expressions that contain [geometry functions](https://developers.arcgis.com/arcade/function-reference/geometry_functions/).
   *
   * @since 4.11
   * @see [Type system](https://developers.arcgis.com/arcade/guide/types/#featuresetcollection)
   * @see [Arcade Profiles: Popup](https://developers.arcgis.com/arcade/profiles/popup/)
   */
  spatialReference?: SpatialReferenceProperties | null;
  /**
   * Dates and times displayed in the widget will be displayed in this time zone. By default this time zone is
   * inherited from [MapView.timeZone](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#timeZone). When a MapView is not associated with the widget
   * then the property will fallback to the `system` time zone.
   *
   * **Possible Values**
   *
   * Value | Description |
   * ----- | ----------- |
   * system  | Dates and times will be displayed in the timezone of the device or browser.
   * unknown | Dates and time are not adjusted for any timezone.
   * Specified IANA timezone | Dates and times will be displayed in the specified IANA time zone. See [wikipedia - List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
   *
   * @since 4.29
   */
  timeZone?: TimeZone | null;
  /**
   * The view model for this widget. This is a class that contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [FeatureViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/FeatureViewModel/) class to access
   * all properties and methods on the widget.
   */
  viewModel?: FeatureViewModelProperties;
}

export interface VisibleContentElements {
  /**
   * Indicates whether to display any [AttachmentsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/AttachmentsContent/) elements.
   *
   * @default true
   */
  attachments?: boolean;
  /**
   * Indicates whether to display any [ExpressionContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/ExpressionContent/) elements.
   *   When defining content for expression elements, the [map](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#map) and [spatialReference](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#spatialReference) properties must be defined
   *   for the expressions to execute and render content in the widget.
   *
   * @default true
   */
  expression?: boolean;
  /**
   * Indicates whether to display any [FieldsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/FieldsContent/) elements.
   *
   * @default true
   */
  fields?: boolean;
  /**
   * Indicates whether to display any [MediaContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) elements.
   *
   * @default true
   */
  media?: boolean;
  /**
   * Indicates whether to display any [RelationshipContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/RelationshipContent/) elements.
   *
   * @default true
   */
  relationship?: boolean;
  /**
   * Indicates whether to display any [TextContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/TextContent/) elements.
   *
   * @default true
   */
  text?: boolean;
}

export interface FeatureVisibleElements {
  /**
   * Indicates whether the title associated with the feature displays.
   *
   * @default true
   */
  title?: boolean;
  /**
   * Indicates
   * whether content for the Feature displays, can also indicate the specific types of content elements
   * by setting it via [VisibleContentElements](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#VisibleContentElements).
   *
   * @default true
   */
  content?: boolean | VisibleContentElements;
  /**
   * Indicates whether [FeatureViewModel.lastEditInfo](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/FeatureViewModel/#lastEditInfo) is displayed
   * within the feature.
   *
   * @default true
   */
  lastEditedInfo?: boolean;
}

/**
 * The Feature widget displays a graphic according to its [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 * This widget is useful in instances where you want to display information about a feature but without
 * the use of a [Popup](https://developers.arcgis.com/javascript/latest/references/core/widgets/Popup/).
 *
 * If wanting to show a feature's content with [PopupTemplate.actions](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/#actions), [related records](https://developers.arcgis.com/javascript/latest/references/core/popup/content/RelationshipContent/), or [clustering configuration](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FeatureReductionCluster/#popupTemplate), etc., then use the [Features](https://developers.arcgis.com/javascript/latest/references/core/widgets/Features/) widget.
 *
 * When Arcade expressions that use `$map` or [geometry functions](https://developers.arcgis.com/arcade/function-reference/geometry_functions/) are defined in any popup template content or as expression elements,
 * the [map](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#map) and [spatialReference](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#spatialReference) properties need to be defined in the Feature widget.
 *
 * @deprecated since version 4.34. Use the [Feature component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-feature/) instead. For information on widget deprecation, read about [Esri's move to web components](https://developers.arcgis.com/javascript/latest/components-transition-plan/).
 * @since 4.7
 * @see [FeatureViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/FeatureViewModel/)
 * @see [Popup](https://developers.arcgis.com/javascript/latest/references/core/widgets/Popup/)
 * @see [DefaultUI](https://developers.arcgis.com/javascript/latest/references/core/views/ui/DefaultUI/)
 * @see [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/)
 * @see [Arcade Profiles: Popup](https://developers.arcgis.com/arcade/profiles/popup/)
 * @see [Arcade - expression language](https://developers.arcgis.com/javascript/latest/arcade/)
 * @example
 * // Create graphic
 * let graphic = new Graphic({
 *   geometry: view.center,
 *   popupTemplate: {
 *     content: [{
 *       // add popupTemplate content
 *     }]
 *   }
 * });
 *
 * // map and spatialReference must be set for Arcade
 * // expressions to execute and display content
 * let feature = new Feature({
 *   graphic: graphic,
 *   map: map,
 *   spatialReference: spatialReference
 * });
 *
 * view.ui.add(feature, "top-right");
 */
export default class Feature extends Widget {
  constructor(properties?: FeatureProperties);
  /**
   * Enables automatic creation of a popup template for layers that have popups enabled but no
   * popupTemplate defined. Automatic popup templates are supported for layers that
   * support the `createPopupTemplate` method. (Supported for
   * [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/),
   * [GeoJSONLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GeoJSONLayer/),
   * [SceneLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/SceneLayer/),
   * [CSVLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/CSVLayer/),
   * [OGCFeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/OGCFeatureLayer/)
   * [PointCloudLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/PointCloudLayer/),
   * [StreamLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/StreamLayer/), and
   * [ImageryLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/)).
   *
   * @default false
   * @since 4.11
   */
  accessor defaultPopupTemplateEnabled: boolean;
  /**
   * The [Graphic](https://developers.arcgis.com/javascript/latest/references/core/Graphic/) used to represent the feature.
   *
   * @see [PopupTemplate.content](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/#content)
   * @example
   * let graphic = new Graphic({
   *   geometry: view.center,
   *   attributes: {
   *     "name": "Spruce",
   *     "family": "Pinaceae",
   *     "count": 126
   *   },
   *   symbol: new SimpleMarkerSymbol({
   *     style: "square",
   *     color: "blue",
   *     size: "8px"
   *   }),
   *   popupTemplate: {
   *     content: [
   *       {
   *         // Set popup template content
   *       }
   *     ]
   *   }
   * });
   */
  get graphic(): Graphic | null | undefined;
  set graphic(value: GraphicProperties | null | undefined);
  /**
   * Indicates the heading level to use for the [title](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#title) of the feature widget.
   * By default, the title is rendered
   * as a level 2 heading (e.g. `<h2>Title of content</h2>`). Depending on the widget's placement
   * in your app, you may need to adjust this heading for proper semantics. This is
   * important for meeting accessibility standards.
   *
   * @default 2
   * @since 4.20
   * @see [Heading Elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements)
   * @example
   * // feature title will render as an <h3>
   * feature.headingLevel = 3;
   */
  accessor headingLevel: HeadingLevel;
  /**
   * Icon which represents the widget. It is typically used when the widget is controlled by another
   * one (e.g. in the Expand widget).
   *
   * @default "polygon"
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  get icon(): Icon["icon"];
  set icon(value: Icon["icon"] | null | undefined);
  /**
   * The widget's default label.
   *
   * @since 4.11
   */
  get label(): string;
  set label(value: string | null | undefined);
  /**
   * The location of the graphic to be displayed.
   *
   * @since 4.31
   */
  get location(): Point | null | undefined;
  set location(value: PointProperties | null | undefined);
  /**
   * A map is required when the input [graphic](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#graphic) has a popupTemplate that contains [Arcade](https://developers.arcgis.com/arcade) expressions in [ExpressionInfo](https://developers.arcgis.com/javascript/latest/references/core/popup/ExpressionInfo/) or [ExpressionContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/ExpressionContent/) that may use the `$map` profile variable to access data from layers within a map. Without a map, expressions that use `$map` will throw an error.
   *
   * Alternatively, the [view](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#view) property can be used to provide the map instance for this property.
   *
   * @since 4.11
   * @see [Type system](https://developers.arcgis.com/arcade/guide/types/#featuresetcollection)
   * @see [Arcade Profiles: Popup](https://developers.arcgis.com/arcade/profiles/popup/)
   * @example
   * // The building footprints represent the buildings that intersect a clicked parcel
   * let buildingFootprints = Intersects($feature, FeatureSetByName($map, "Building Footprints"));
   */
  accessor map: EsriMap | null | undefined;
  /**
   * The spatial reference used for [Arcade](https://developers.arcgis.com/arcade) operations.
   * This property should be set if the Feature widget executes Arcade expressions that contain [geometry functions](https://developers.arcgis.com/arcade/function-reference/geometry_functions/).
   *
   * @since 4.11
   * @see [Type system](https://developers.arcgis.com/arcade/guide/types/#featuresetcollection)
   * @see [Arcade Profiles: Popup](https://developers.arcgis.com/arcade/profiles/popup/)
   */
  get spatialReference(): SpatialReference | null | undefined;
  set spatialReference(value: SpatialReferenceProperties | null | undefined);
  /**
   * Dates and times displayed in the widget will be displayed in this time zone. By default this time zone is
   * inherited from [MapView.timeZone](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#timeZone). When a MapView is not associated with the widget
   * then the property will fallback to the `system` time zone.
   *
   * **Possible Values**
   *
   * Value | Description |
   * ----- | ----------- |
   * system  | Dates and times will be displayed in the timezone of the device or browser.
   * unknown | Dates and time are not adjusted for any timezone.
   * Specified IANA timezone | Dates and times will be displayed in the specified IANA time zone. See [wikipedia - List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
   *
   * @since 4.29
   */
  get timeZone(): TimeZone;
  set timeZone(value: TimeZone | null | undefined);
  /**
   * The title for the feature. You can disable this via the [visibleElements](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#visibleElements) property.
   *
   * @see [headingLevel](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#headingLevel)
   */
  get title(): string;
  /**
   * A reference to the [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) or [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/). Set this to link the widget to a specific view.
   *
   * > [!WARNING]
   * >
   * > The Feature widget requires a view if the user expects it to display content in any of the following situations:
   * > - The [graphic](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/#graphic) has a popupTemplate containing Arcade expressions in [ExpressionInfo](https://developers.arcgis.com/javascript/latest/references/core/popup/ExpressionInfo/) or [ExpressionContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/ExpressionContent/) that use [geometry functions](https://developers.arcgis.com/arcade/function-reference/geometry_functions/) or reference the `$map` profile variable (i.e. access data from layers within a map).
   * > - Content is displayed from the popup template of an [aggregate feature](https://developers.arcgis.com/javascript/latest/references/core/Graphic/#isAggregate) (i.e. a [cluster](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FeatureReductionCluster/) or [bin](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FeatureReductionBinning/)).
   * > - Values from `date` and `timestamp-offset` [fields](https://developers.arcgis.com/javascript/latest/references/core/layers/support/Field/#type) should respect the view's [time zone](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#timeZone).
   */
  accessor view: MapViewOrSceneView | null | undefined;
  /**
   * The view model for this widget. This is a class that contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [FeatureViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/Feature/FeatureViewModel/) class to access
   * all properties and methods on the widget.
   */
  get viewModel(): FeatureViewModel;
  set viewModel(value: FeatureViewModelProperties);
  /**
   * The visible elements that are displayed within the widget's [graphic.popupTemplate.content](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/#content).
   * This property provides the ability to turn individual elements of the widget's display on/off.
   * See the [PopupTemplate.content](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/#content) documentation
   * for additional information on how these elements work.
   *
   * @since 4.11
   * @see [PopupTemplate.content](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/#content)
   */
  accessor visibleElements: FeatureVisibleElements;
  /**
   * Paginates to the next [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) info.
   *
   * @param contentElementIndex - The index position of the [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) content element.
   */
  nextMedia(contentElementIndex: number): void;
  /**
   * Paginates to the previous [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) info in the specified
   * [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) content element.
   *
   * @param contentElementIndex - The index position of the [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) content element.
   */
  previousMedia(contentElementIndex: number): void;
  /**
   * Paginates to a specified [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) info object. For example,
   * you may have [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) content which contains
   * multiple `mediaInfos`. This method allows you to specify the index of the `mediaInfos`
   * you wish to display.
   *
   * > [!WARNING]
   * >
   * > Prior to   version 4.17, this method was named `goToMedia`.
   *
   * @param contentElementIndex - The index position of the [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) content element to be updated.
   * @param mediaInfoIndex - The index position of the [media](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/) info object you wish to display.
   */
  setActiveMedia(contentElementIndex: number, mediaInfoIndex: number): void;
}