import type LayerBase from "../../layers/Layer.js";
import type SearchSource from "./SearchSource.js";
import type { SearchSourceProperties } from "./SearchSource.js";

export interface LayerSearchSourceProperties<Layer extends LayerBase = LayerBase> extends SearchSourceProperties, Partial<Pick<LayerSearchSource<Layer>, "displayField" | "exactMatch" | "layer" | "orderByFields" | "searchFields" | "searchTemplate" | "suggestionTemplate">> {
  /** The name of the source for display. */
  name?: string | null;
}

/**
 * The following properties define a
 * [Layer](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/)-based [source](https://developers.arcgis.com/javascript/latest/references/core/widgets/Search/#sources) whose
 * features may be searched by a [Search widget](https://developers.arcgis.com/javascript/latest/references/core/widgets/Search/) or [Search component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-search/).
 *
 * For `string` field searches, there is no leading wildcard. This effectively makes [exactMatch](https://developers.arcgis.com/javascript/latest/references/core/widgets/Search/LayerSearchSource/#exactMatch)
 * `true`, which will remove unnecessary search results and suggestions.
 *
 * > [!WARNING]
 * >
 * > Layers created from client-side graphics are not supported.
 *
 * @since 4.11
 * @see [Search widget](https://developers.arcgis.com/javascript/latest/references/core/widgets/Search/) - _Deprecated since 4.33. Use the [Search component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-search/) instead._
 * @see [Search component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-search/)
 * @see [Sample - Search component with multiple sources](https://developers.arcgis.com/javascript/latest/sample-code/search-component-multisource/)
 */
export default class LayerSearchSource<Layer extends LayerBase = LayerBase> extends SearchSource {
  constructor(properties?: LayerSearchSourceProperties);
  /**
   * The results are displayed using this field. Defaults
   * to the layer's `displayField` or the first string field.
   */
  accessor displayField: string | null | undefined;
  /**
   * Indicates to only return results that match the
   * search value exactly.
   * This property only applies to `string` field searches. `exactMatch` is always
   * `true` when searching fields of type `number`.
   *
   * @default false
   */
  accessor exactMatch: boolean | null | undefined;
  /**
   * The layer queried in the search. This is **required**.
   * The layer can be a [map](https://developers.arcgis.com/javascript/latest/references/core/layers/MapImageLayer/)/[feature](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) service feature
   * layer(s), [SceneLayers](https://developers.arcgis.com/javascript/latest/references/core/layers/SceneLayer/) with an associated feature layer,
   * [BuildingComponentSublayer](https://developers.arcgis.com/javascript/latest/references/core/layers/buildingSublayers/BuildingComponentSublayer/) with an associated feature layer,
   * [GeoJSONLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GeoJSONLayer/), [CSVLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/CSVLayer/) or [OGCFeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/OGCFeatureLayer/).
   * See the [SceneLayer Guide page](https://developers.arcgis.com/javascript/latest/working-with-scene-layers/)
   * on how to publish SceneLayers with associated feature layers.
   *
   * The geometry type of the layer affects the behavior when a result is found. If the layer type is [Point](https://developers.arcgis.com/javascript/latest/references/core/geometry/Point/),
   * the view will pan, but not zoom, to the result. If the layer type is [Polygon](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/) or
   * [Polyline](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polyline/), the view will pan and zoom to the result.
   *
   * > [!WARNING]
   * >
   * > Feature layers created from client-side graphics are not supported.
   */
  accessor layer: Layer;
  /** The name of the source for display. */
  get name(): string;
  set name(value: string | null | undefined);
  /**
   * One or more field names used to order the query results. Specify `ASC` (ascending) or `DESC`
   * (descending) after the field name to control the order. The default order is `ASC`.
   */
  accessor orderByFields: string[] | null | undefined;
  /**
   * An array of string values representing the
   * names of fields in the feature layer to search.
   */
  accessor searchFields: string[] | null | undefined;
  /**
   * A template string used to display multiple
   * fields in a defined order when results are displayed.
   *
   * @example LayerSearchSource.searchTemplate = "{County}, {State}";
   */
  accessor searchTemplate: string | null | undefined;
  /**
   * A template string used to display multiple
   * fields in a defined order
   * when suggestions are displayed. This takes precedence over `displayField`.
   * Field names in the template must have the following
   * format: `{FieldName}`. An example suggestionTemplate could look something
   * like: `Name: {OWNER}, Parcel: {PARCEL_ID}`.
   *
   * @example LayerSearchSource.suggestionTemplate = "Name: {OWNER}, Parcel: {PARCEL_ID}";
   */
  accessor suggestionTemplate: string | null | undefined;
  /**
   * Creates a deep clone of this object.
   *
   * @returns A clone of the new [LayerSearchSource](https://developers.arcgis.com/javascript/latest/references/core/widgets/Search/LayerSearchSource/) instance.
   */
  clone(): LayerSearchSource<Layer>;
}