import type Extent from "../../geometry/Extent.js";
import type Point from "../../geometry/Point.js";
import type PlacesParameters from "./PlacesParameters.js";
import type { PlacesParametersProperties } from "./PlacesParameters.js";
import type { ExtentProperties } from "../../geometry/Extent.js";
import type { PointProperties } from "../../geometry/Point.js";

export interface PlacesQueryParametersProperties extends PlacesParametersProperties, Partial<Pick<PlacesQueryParameters, "categoryIds" | "offset" | "pageSize" | "radius" | "searchText">> {
  /**
   * The extent of the bounding box to be searched inside.
   * This is **required** for the
   * [queryPlacesWithinExtent()](https://developers.arcgis.com/javascript/latest/references/core/rest/places/#queryPlacesWithinExtent) method.
   *
   * The total width of the extent must be less than 20,000 meters, and
   * the total height of the extent must be less than 20,000 meters.
   *
   * @see [Extent](https://developers.arcgis.com/javascript/latest/references/core/geometry/Extent/)
   * @example
   * const [places, PlacesQueryParameters, Extent] = await $arcgis.import([
   *  "@arcgis/core/rest/places.js",
   *  "@arcgis/core/rest/support/PlacesQueryParameters.js",
   *  "@arcgis/core/geometry/Extent.js"
   * );
   * const extent = new Extent({
   *   xmin: 17.75,
   *   ymin: 59.55,
   *   xmax: 18,
   *   ymax: 59.7,
   *   spatialReference: SpatialReference.WGS84
   * });
   *
   * const swedishPlacesQueryParameters = new PlacesQueryParameters({
   *   apiKey: "YOUR_API_KEY",
   *   categoryIds: ["4d4b7105d754a06377d81259"], // Landmarks and Outdoors
   *   extent,
   *   offset: 2,
   *   searchText: "Värma"
   * });
   *
   * function findPlaces() {
   *   places.queryPlacesWithinExtent(swedishPlacesQueryParameters).then(showPlaces);
   * }
   *
   * function showPlaces(placesSolveResult) {
   *   // results from the queryPlacesWithinExtent() method
   *   console.log("PlacesQueryResult: ", placesSolveResult);
   *   // first PlaceResult object from PlacesQueryResult.results
   *   console.log("PlaceResult: ", placesSolveResult.results[0]);
   * }
   *
   * findPlaces();
   */
  extent?: ExtentProperties | null;
  /**
   * A location defined by X and Y coordinates.
   * This is **required** for the
   * [queryPlacesNearPoint()](https://developers.arcgis.com/javascript/latest/references/core/rest/places/#queryPlacesNearPoint) method.
   *
   * @see [Point](https://developers.arcgis.com/javascript/latest/references/core/geometry/Point/)
   * @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,
   *   searchText: "Bygg",
   *   pageSize: 11
   * });
   *
   * function findPlaces() {
   *   places.queryPlacesNearPoint(swedishPlacesQueryParameters).then(showPlaces);
   * }
   *
   * function showPlaces(placesSolveResult) {
   *   // results from the queryPlacesNearPoint() method
   *   console.log("PlacesQueryResult: ", placesSolveResult);
   *   // first PlaceResult object from PlacesQueryResult.results
   *   console.log("PlaceResult: ", placesSolveResult.results[0]);
   * }
   *
   * findPlaces();
   */
  point?: PointProperties | null;
}

/**
 * The following properties define the parameters for the
 * [queryPlacesNearPoint()](https://developers.arcgis.com/javascript/latest/references/core/rest/places/#queryPlacesNearPoint) and
 * [queryPlacesWithinExtent()](https://developers.arcgis.com/javascript/latest/references/core/rest/places/#queryPlacesWithinExtent) methods pointing to a
 * [url](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PlacesQueryParameters/#url) that represents a places service.
 * The places service is a ready-to-use service that can search for businesses and geographic locations around the world.
 * It allows you to discover, locate, and return detailed information about a place.
 *
 * @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 category finder](https://developers.arcgis.com/documentation/mapping-apis-and-services/places/places-category-finder/)
 * @see [Places service](https://developers.arcgis.com/rest/places/)
 * @see [places](https://developers.arcgis.com/javascript/latest/references/core/rest/places/)
 * @see [PlacesParameters](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PlacesParameters/)
 * @see [FetchPlaceParameters](https://developers.arcgis.com/javascript/latest/references/core/rest/support/FetchPlaceParameters/)
 */
export default class PlacesQueryParameters extends PlacesParameters {
  constructor(properties?: PlacesQueryParametersProperties);
  /**
   * Filters places to those that match the category Ids.
   * Places will be returned if they match any of the category Ids.
   * If this property is not set, places will be returned regardless of their category.
   *
   * You can search up to a maximum of **10** category Ids.
   *
   * @see [Places category finder](https://developers.arcgis.com/documentation/mapping-apis-and-services/places/places-category-finder/)
   */
  accessor categoryIds: string[] | null | undefined;
  /**
   * The extent of the bounding box to be searched inside.
   * This is **required** for the
   * [queryPlacesWithinExtent()](https://developers.arcgis.com/javascript/latest/references/core/rest/places/#queryPlacesWithinExtent) method.
   *
   * The total width of the extent must be less than 20,000 meters, and
   * the total height of the extent must be less than 20,000 meters.
   *
   * @see [Extent](https://developers.arcgis.com/javascript/latest/references/core/geometry/Extent/)
   * @example
   * const [places, PlacesQueryParameters, Extent] = await $arcgis.import([
   *  "@arcgis/core/rest/places.js",
   *  "@arcgis/core/rest/support/PlacesQueryParameters.js",
   *  "@arcgis/core/geometry/Extent.js"
   * );
   * const extent = new Extent({
   *   xmin: 17.75,
   *   ymin: 59.55,
   *   xmax: 18,
   *   ymax: 59.7,
   *   spatialReference: SpatialReference.WGS84
   * });
   *
   * const swedishPlacesQueryParameters = new PlacesQueryParameters({
   *   apiKey: "YOUR_API_KEY",
   *   categoryIds: ["4d4b7105d754a06377d81259"], // Landmarks and Outdoors
   *   extent,
   *   offset: 2,
   *   searchText: "Värma"
   * });
   *
   * function findPlaces() {
   *   places.queryPlacesWithinExtent(swedishPlacesQueryParameters).then(showPlaces);
   * }
   *
   * function showPlaces(placesSolveResult) {
   *   // results from the queryPlacesWithinExtent() method
   *   console.log("PlacesQueryResult: ", placesSolveResult);
   *   // first PlaceResult object from PlacesQueryResult.results
   *   console.log("PlaceResult: ", placesSolveResult.results[0]);
   * }
   *
   * findPlaces();
   */
  get extent(): Extent | null | undefined;
  set extent(value: ExtentProperties | null | undefined);
  /**
   * Request results starting from the given offset.
   *
   * This parameter works with the [pageSize](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PlacesQueryParameters/#pageSize) property to get results from subsequent pages.
   * For example, with `pageSize = 2`, setting the offset to 2 would return the 3rd and 4th results.
   * Regardless of paging, the maximum number of places that can be returned by a single query is **200**.
   *
   * @default 0
   */
  accessor offset: number;
  /**
   * The number of places that should be sent in the response for a single request.
   *
   * You can set this to any value up to **20** when you need to control the size of responses that the app downloads.
   * If the query results in more than this page size, then the response object will contain a `next` url fragment.
   * This fragment can be used to form a request url to fetch the next page of results.
   * The maximum number of places that can be returned in total is **200**.
   *
   * @default 10
   */
  accessor pageSize: number;
  /**
   * A location defined by X and Y coordinates.
   * This is **required** for the
   * [queryPlacesNearPoint()](https://developers.arcgis.com/javascript/latest/references/core/rest/places/#queryPlacesNearPoint) method.
   *
   * @see [Point](https://developers.arcgis.com/javascript/latest/references/core/geometry/Point/)
   * @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,
   *   searchText: "Bygg",
   *   pageSize: 11
   * });
   *
   * function findPlaces() {
   *   places.queryPlacesNearPoint(swedishPlacesQueryParameters).then(showPlaces);
   * }
   *
   * function showPlaces(placesSolveResult) {
   *   // results from the queryPlacesNearPoint() method
   *   console.log("PlacesQueryResult: ", placesSolveResult);
   *   // first PlaceResult object from PlacesQueryResult.results
   *   console.log("PlaceResult: ", placesSolveResult.results[0]);
   * }
   *
   * findPlaces();
   */
  get point(): Point | null | undefined;
  set point(value: PointProperties | null | undefined);
  /**
   * The radius in meters to search for places, measured from the supplied [point](https://developers.arcgis.com/javascript/latest/references/core/rest/support/PlacesQueryParameters/#point).
   * This property is only used by the
   * [queryPlacesNearPoint()](https://developers.arcgis.com/javascript/latest/references/core/rest/places/#queryPlacesNearPoint) method.
   * The maximum value is **10,000**.
   *
   * @default 1000
   */
  accessor radius: number;
  /**
   * Free search text for places against names, categories, etc.
   * The value must be a string between 3 and 255 characters long.
   */
  accessor searchText: string | null | undefined;
  /**
   * Creates a deep clone of the instance of PlacesQueryParameters that this method is called on.
   *
   * @returns A clone of the instance that this method is called on.
   */
  clone(): PlacesQueryParameters;
}