import type Accessor from "../../core/Accessor.js";
import type Point from "../../geometry/Point.js";
import type { PointProperties } from "../../geometry/Point.js";

export interface PlaceResultProperties extends Partial<Pick<PlaceResult, "categories" | "distance" | "icon" | "name" | "placeId">> {
  /**
   * A location defined by X and Y coordinates in WGS84.
   *
   * @see [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html)
   */
  location?: PointProperties;
}

/**
 * The `PlaceResult` object includes a single place that satisfies the search and
 * either: the distance from the [search point](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PlacesQueryParameters.html#point)
 * in meters, or falls within the [PlacesQueryParameters.extent](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PlacesQueryParameters.html#extent) of the search.
 * The [PlacesQueryResult.results](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PlacesQueryResult.html#results) property is an array
 * of these objects.
 *
 * @since 4.27
 * @see [Sample -  Find nearby places and details](https://developers.arcgis.com/javascript/latest/sample-code/places/)
 * @see [Introduction to places](https://developers.arcgis.com/documentation/mapping-apis-and-services/places/)
 * @see [Places service](https://developers.arcgis.com/rest/places/)
 * @see [places](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-places.html)
 * @see [PlacesParameters](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PlacesParameters.html)
 * @see [PlacesQueryParameters](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PlacesQueryParameters.html)
 * @see [PlacesQueryResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PlacesQueryResult.html)
 * @example
 * const [places, PlacesQueryParameters] = await $arcgis.import([
 *  "@arcgis/core/rest/places.js",
 *  "@arcgis/core/rest/support/PlacesQueryParameters.js"
 * ]);
 * const point = {
 *   type: "point", // autocasts as new Point()
 *   longitude: 17.81840,
 *   latitude: 59.42145
 * };
 *
 * const swedishPlacesQueryParameters = new PlacesQueryParameters({
 *   apiKey: "YOUR_API_KEY",
 *   categoryIds: ["63be6904847c3692a84b9b4c"], // Bathroom Contractor
 *   radius: 10000,  // set radius to 10,000 meters
 *   point
 * });
 *
 * function findPlaces() {
 *   places.queryPlacesNearPoint(swedishPlacesQueryParameters).then(showPlaces);
 * }
 *
 * function showPlaces(placesSolveResult) {
 *   // first PlaceResult object from PlacesQueryResult.results
 *   console.log("PlaceResult: ", placesSolveResult.results[0]);
 * }
 *
 * findPlaces();
 */
export default class PlaceResult extends Accessor {
  constructor(properties?: PlaceResultProperties);
  /**
   * An array of category objects for a place. Each category object has a
   * categoryId and a label. A category describes a type of place, such as
   * "movie theater" or "zoo".
   *
   * Categories are uniquely identified by a categoryId. For example, 17119 identifies a "Bicycle Store"
   * and 10051 identifies a "Stadium". Note that a single place can belong to multiple categories
   * (for example, a gas station could also have a super-market).
   *
   * @see [categories](https://developers.arcgis.com/rest/places/categories-get/)
   * @see [Places category finder](https://developers.arcgis.com/documentation/mapping-apis-and-services/places/places-category-finder/)
   */
  accessor categories: Category[];
  /**
   * The distance, in meters, from the place to the search point.
   * This property is only returned by the
   * [queryPlacesNearPoint()](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-places.html#queryPlacesNearPoint) method.
   */
  accessor distance: number | null | undefined;
  /**
   * Url for an icon for this place in either cim, png or svg format.
   *
   * @since 4.30
   * @see [PlacesParameters.icon](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PlacesParameters.html#icon)
   */
  accessor icon: { url: string; } | null | undefined;
  /**
   * A location defined by X and Y coordinates in WGS84.
   *
   * @see [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html)
   */
  get location(): Point;
  set location(value: PointProperties);
  /**
   * The name of the place, or point of interest.
   * You can search for places by name using the [PlacesQueryParameters.searchText](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PlacesQueryParameters.html#searchText)
   * property in the [queryPlacesNearPoint()](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-places.html#queryPlacesNearPoint) and
   * [queryPlacesWithinExtent()](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-places.html#queryPlacesWithinExtent) methods.
   */
  accessor name: string;
  /**
   * The unique Id of this place.
   * This place Id can be passed to the places/{placeId} endpoint to retrieve additional details.
   *
   * @see [places/{placeId}](https://developers.arcgis.com/rest/places/place-id-get/)
   */
  accessor placeId: string;
}

/**
 * Each category object has a categoryId and a label. A category describes a type of place,
 * such as "petting zoo" or "zoo".
 */
export interface Category {
  /** The Id of the category of the place. Categories are uniquely identified by a categoryId. */
  categoryId: number;
  /** The name of the the category. */
  label: string;
}