import type Extent from "../../geometry/Extent.js";
import type Point from "../../geometry/Point.js";
import type SpatialReference from "../../geometry/SpatialReference.js";
import type { JSONSupport, JSONSupportMixinProperties } from "../../core/JSONSupport.js";
import type { LocationType } from "../types.js";
import type { PointProperties } from "../../geometry/Point.js";
import type { SpatialReferenceProperties } from "../../geometry/SpatialReference.js";
import type { ExtentProperties } from "../../geometry/Extent.js";

export interface AddressToLocationsParametersProperties extends JSONSupportMixinProperties, Partial<Pick<AddressToLocationsParameters, "address" | "categories" | "countryCode" | "forStorage" | "locationType" | "magicKey" | "maxLocations" | "outFields">> {
  /**
   * Used to weight returned results for a specified area.
   * Only used when the scale of the [MapView#scale](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#scale) or
   * [SceneView#scale](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-SceneView.html#scale) is less than or equal to 300,000.
   */
  location?: PointProperties | null;
  /**
   * The spatial reference of the output geometries. If not specified, the output geometries are in the spatial reference of
   * the input geometries when performing a reverse geocode and in the default spatial reference returned by the service if
   * finding locations by address.
   */
  outSpatialReference?: SpatialReferenceProperties | null;
  /**
   * Defines the extent within which the geocode server will search.
   * Requires ArcGIS Server version 10.1 or greater.
   */
  searchExtent?: ExtentProperties | null;
}

export default abstract class AddressToLocationsParameters extends JSONSupport {
  /**
   * The address argument is data object that contains properties representing the various
   *                                address fields accepted by the corresponding geocode service. These fields are listed in the
   *                                addressFields property of the associated geocode service resource.
   * For example, if the *addressFields* of a geocode service resource includes fields with the following names:
   * Street, City, State and Zone, then the address argument is of the form:
   *
   * ```js
   * {
   *   Street: "1234 W Main St",
   *   City: "Small Town",
   *   State: "WA",
   *   Zone: "99027"
   * }
   * ```
   *
   * Locators published using ArcGIS 10 or later support a single line address field, which
   * can be specified using the following syntax where field_name is the name of the single
   * line address field. You can find this name by viewing the help or services directory for
   * your locator services. Common values are *SingleLine* and *SingleLineFieldName*:
   *
   * ```js
   * const address = {
   *   "field_name": "380 New York St, Redlands, CA 92373"
   * };
   * ```
   * The Services Directory can be used to find out the required and optional address fields
   * and the correct names for the input name fields. If you are using the World Geocoding Service
   * visit the ArcGIS Online Geocoding Service help for more details on the World Geocoder.
   */
  accessor address: any;
  /**
   * Limit result to one or more categories. For example,
   * "Populated Place" or "Scandinavian Food". Only applies to the World Geocode Service.
   * See [Category filtering (World Geocoding Service)](https://developers.arcgis.com/rest/geocode/api-reference/geocoding-category-filtering.htm#ESRI_SECTION1_502B3FE2028145D7B189C25B1A00E17B) for more information.
   */
  accessor categories: string[] | null | undefined;
  /**
   * Limit result to a specific country. For example, "US" for United States or "SE" for Sweden.
   * Only applies to the World Geocode Service. See Geocode coverage (World Geocoding Service)
   * for more information.
   */
  accessor countryCode: string | null;
  /** Allows the results of single geocode transactions to be persisted. */
  accessor forStorage: boolean | null;
  /**
   * Used to weight returned results for a specified area.
   * Only used when the scale of the [MapView#scale](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#scale) or
   * [SceneView#scale](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-SceneView.html#scale) is less than or equal to 300,000.
   */
  get location(): Point | null | undefined;
  set location(value: PointProperties | null | undefined);
  /**
   * Define the type of location, either `"street"` or `"rooftop"`, of the point returned from the
   * [World Geocoding Service](https://developers.arcgis.com/rest/geocode/api-reference/geocoding-category-filtering.htm).
   */
  accessor locationType: LocationType | null | undefined;
  /** A `suggestLocations` result ID (magicKey). Used to query for a specific results information. */
  accessor magicKey: string | null | undefined;
  /** Maximum results to return from the query. */
  accessor maxLocations: number | null | undefined;
  /**
   * The list of fields included in the returned result set. This list is a comma delimited
   * list of field names. If you specify the shape field in the list of return fields, it is ignored.
   * For non-intersection addresses you can specify the candidate fields as defined in the geocode
   * service. For intersection addresses you can specify the intersection candidate fields.
   */
  accessor outFields: string[] | null | undefined;
  /**
   * The spatial reference of the output geometries. If not specified, the output geometries are in the spatial reference of
   * the input geometries when performing a reverse geocode and in the default spatial reference returned by the service if
   * finding locations by address.
   */
  get outSpatialReference(): SpatialReference | null | undefined;
  set outSpatialReference(value: SpatialReferenceProperties | null | undefined);
  /**
   * Defines the extent within which the geocode server will search.
   * Requires ArcGIS Server version 10.1 or greater.
   */
  get searchExtent(): Extent | null | undefined;
  set searchExtent(value: ExtentProperties | null | undefined);
}