import type Graphic from "../../Graphic.js";
import type Polyline from "../../geometry/Polyline.js";
import type DirectionsEvent from "./DirectionsEvent.js";
import type DirectionsString from "./DirectionsString.js";
import type { DirectionsEventProperties } from "./DirectionsEvent.js";
import type { PolylineProperties } from "../../geometry/Polyline.js";
import type { DirectionsStringProperties } from "./DirectionsString.js";
import type { GraphicProperties } from "../../Graphic.js";

export interface DirectionsFeatureProperties extends GraphicProperties {
  /**
   * Name-value pairs of fields and field values associated with the Directions Feature. Fields include the following:
   * | Field name    | Type   | Description |
   * |---------------|--------|-------------|
   * | ETA           | Number | The estimated arrival time in UTC in the local time zone. |
   * | arriveTimeUTC | Number | The estimated arrival time in UTC.                        |
   * | length        | Number | The length of the route segment.                          |
   * | maneuverType  | String | The maneuver type.                                        |
   * | text          | String | The driving direction text.                               |
   * | time          | Number | The time spent travelling along the route segment.        |
   *
   * @example
   * let graphic = new Graphic();
   * graphic.attributes = {
   *   "name": "Spruce",
   *   "family": "Pinaceae",
   *   "count": 126
   * };
   */
  attributes?: any;
  /** An array of [Directions Events](https://developers.arcgis.com/javascript/latest/references/core/rest/support/DirectionsEvent/). */
  events?: DirectionsEventProperties[] | null;
  /**
   * The geometry of the Directions Feature.
   *
   * @example
   * // First create a point geometry
   * let point = {
   *   type: "point",  // autocasts as new Point()
   *   longitude: -71.2643,
   *   latitude: 42.0909
   * };
   *
   * // Create a symbol for drawing the point
   * let markerSymbol = {
   *   type: "simple-marker",  // autocasts as new SimpleMarkerSymbol()
   *   color: [226, 119, 40]
   * };
   *
   * // Create a graphic and add the geometry and symbol to it
   * let pointGraphic = new Graphic({
   *   geometry: point,
   *   symbol: markerSymbol
   * });
   */
  geometry?: (PolylineProperties & { type: "polyline" }) | null;
  /** An array of [direction strings](https://developers.arcgis.com/javascript/latest/references/core/rest/support/DirectionsString/). */
  strings?: DirectionsStringProperties[] | null;
}

/**
 * DirectionsFeature is subclass of [Graphic](https://developers.arcgis.com/javascript/latest/references/core/Graphic/) that contains routing specific attributes.
 * This is accessible from the
 * [DirectionsFeatureSet.features](https://developers.arcgis.com/javascript/latest/references/core/rest/support/DirectionsFeatureSet/#features) property.
 *
 * A [DirectionsFeatureSet](https://developers.arcgis.com/javascript/latest/references/core/rest/support/DirectionsFeatureSet/) is only returned when a [route](https://developers.arcgis.com/javascript/latest/references/core/rest/route/) is
 * [solved](https://developers.arcgis.com/javascript/latest/references/core/rest/route/#solve) with an
 * [output type](https://developers.arcgis.com/javascript/latest/references/core/rest/support/RouteParameters/#directionsOutputType) of `"complete"`,
 * `"complete-no-events"`, `"instructions-only"`, `"standard"`, or `"summary-only"`.
 *
 * @since 4.25
 * @see [DirectionsFeatureSet.features](https://developers.arcgis.com/javascript/latest/references/core/rest/support/DirectionsFeatureSet/#features)
 * @see [solve()](https://developers.arcgis.com/javascript/latest/references/core/rest/route/#solve)
 * @example
 * // If I leave Esri now, what time will I arrive at the Redlands Bowl?
 * const apiKey = "<ENTER YOUR API KEY HERE>";
 * const url = "https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World";
 *
 * const spatialReference = SpatialReference.WebMercator;
 *
 * const stops = new Collection([
 *   new Stop({
 *     name: "Esri",
 *     geometry: new Point({ x: -13046165, y: 4036335, spatialReference })
 *   }),
 *   new Stop({
 *     name: "Redland Bowl",
 *     geometry: new Point({ x: -13045111, y: 4036114, spatialReference })
 *   })
 * ]);
 *
 * const routeParameters = new RouteParameters({
 *   apiKey,
 *   stops,
 *   startTime: new Date(),
 *   outSpatialReference: spatialReference,
 *   returnDirections: true,
 *   directionsOutputType: "standard" // default value
 * });
 *
 * const { routeResults } = await route.solve(url, routeParameters);
 * const { directions } = routeResults[0];
 * const directionFeatures = directions.features;
 *
 * const lastDirectionFeature = directionFeatures[directionFeatures.length - 1];
 * const arriveTimeEpoch = lastDirectionFeature.attributes["arriveTimeUTC"];
 * const arriveTimeDate = new Date(arriveTimeEpoch);
 *
 * console.log(`I will arrive at: ${arriveTimeDate.toLocaleTimeString()}`);
 */
export default class DirectionsFeature extends Graphic {
  constructor(properties?: DirectionsFeatureProperties);
  /**
   * Name-value pairs of fields and field values associated with the Directions Feature. Fields include the following:
   * | Field name    | Type   | Description |
   * |---------------|--------|-------------|
   * | ETA           | Number | The estimated arrival time in UTC in the local time zone. |
   * | arriveTimeUTC | Number | The estimated arrival time in UTC.                        |
   * | length        | Number | The length of the route segment.                          |
   * | maneuverType  | String | The maneuver type.                                        |
   * | text          | String | The driving direction text.                               |
   * | time          | Number | The time spent travelling along the route segment.        |
   *
   * @example
   * let graphic = new Graphic();
   * graphic.attributes = {
   *   "name": "Spruce",
   *   "family": "Pinaceae",
   *   "count": 126
   * };
   */
  accessor attributes: any;
  /** An array of [Directions Events](https://developers.arcgis.com/javascript/latest/references/core/rest/support/DirectionsEvent/). */
  get events(): DirectionsEvent[] | null | undefined;
  set events(value: DirectionsEventProperties[] | null | undefined);
  /**
   * The geometry of the Directions Feature.
   *
   * @example
   * // First create a point geometry
   * let point = {
   *   type: "point",  // autocasts as new Point()
   *   longitude: -71.2643,
   *   latitude: 42.0909
   * };
   *
   * // Create a symbol for drawing the point
   * let markerSymbol = {
   *   type: "simple-marker",  // autocasts as new SimpleMarkerSymbol()
   *   color: [226, 119, 40]
   * };
   *
   * // Create a graphic and add the geometry and symbol to it
   * let pointGraphic = new Graphic({
   *   geometry: point,
   *   symbol: markerSymbol
   * });
   */
  get geometry(): Polyline | null | undefined;
  set geometry(value: (PolylineProperties & { type: "polyline" }) | null | undefined);
  /** An array of [direction strings](https://developers.arcgis.com/javascript/latest/references/core/rest/support/DirectionsString/). */
  get strings(): DirectionsString[] | null | undefined;
  set strings(value: DirectionsStringProperties[] | null | undefined);
}