import type Extent from "../geometry/Extent.js";
import type SpatialReference from "../geometry/SpatialReference.js";
import type UtilityNetwork from "./UtilityNetwork.js";
import type NamedTraceConfiguration from "./support/NamedTraceConfiguration.js";
import type NetworkSystemLayers from "./support/NetworkSystemLayers.js";
import type TopologyValidationJobInfo from "./support/TopologyValidationJobInfo.js";
import type PortalItem from "../portal/PortalItem.js";
import type NetworkElement from "../rest/networks/support/NetworkElement.js";
import type ValidateNetworkTopologyResult from "../rest/networks/support/ValidateNetworkTopologyResult.js";
import type { Loadable, LoadableMixinProperties } from "../core/Loadable.js";
import type { MultiOriginJSONSupportMixin } from "../core/MultiOriginJSONSupport.js";
import type { UrlObject } from "../core/urlUtils.js";
import type { NetworkDataElementJSON } from "./support/jsonTypes.js";
import type { LayerInfo } from "./support/utils.js";
import type { RequestOptions } from "../request/types.js";
import type { QueryNamedTraceConfigurationsParametersProperties } from "../rest/networks/support/QueryNamedTraceConfigurationsParameters.js";
import type { ValidateNetworkTopologyParametersProperties } from "../rest/networks/support/ValidateNetworkTopologyParameters.js";
import type { ExtentProperties } from "../geometry/Extent.js";
import type { SpatialReferenceProperties } from "../geometry/SpatialReference.js";

export interface NetworkProperties extends LoadableMixinProperties, Partial<Pick<Network, "dataElement" | "gdbVersion" | "id" | "layerUrl" | "sourceJSON" | "title">> {
  /** The full extent of the network, defined from the service territory used to create the network. */
  fullExtent?: ExtentProperties | null;
  /**
   * The historic moment to query. If historicMoment is not specified, the query
   * will apply to the current features.
   */
  historicMoment?: (Date | number | string) | null;
  /** The spatial reference of the network, defined at the creation of the network, usually from the service territory class. */
  spatialReference?: SpatialReferenceProperties;
}

/**
 * ValidateTopologyProps represents the parameters for validating a network topology.
 *
 * @since 4.27
 * @example
 * const validationResult = await network.validateTopology({
 *   validateArea: extent,
 *   gdbVersion: "sde.DEFAULT",
 *   validationType: "rebuild",
 *   validationSet: [
 *     {
 *       sourceId: 4134325151,
 *       globalIds: ["{7865BAA6-ED9C-4346-9F72-894A49E10C73}"]
 *     }
 *   ]
 * });
 */
export type ValidateTopologyProperties = Pick<ValidateNetworkTopologyParametersProperties, "validationType" | "validateArea" | "validationSet" | "outSpatialReference">;

/**
 * Class defining high level properties that describes utility networks and trace networks.
 *
 * @since 4.20
 * @see [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/)
 */
export default class Network extends NetworkSuperclass {
  /**
   * Creates a new network instance from an
   * ArcGIS Online or ArcGIS Enterprise
   * [portal item](https://developers.arcgis.com/javascript/latest/references/core/portal/PortalItem/).
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > This method does not populate the [UtilityNetwork.sharedNamedTraceConfigurations](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/#sharedNamedTraceConfigurations) for a [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/) instance.
   *
   * @param params - The parameters for loading the portal item.
   * @returns Returns a promise which resolves to the new utility network instance.
   * @example
   * // Create a utility network from a specified portal item that contains a utility network feature service
   * const item = new PortalItem({
   *   id: "77c7ae75eb3e4e08a7ad98cb37fefe88",
   * });
   *
   * const utilityNetwork = await UtilityNetwork.fromPortalItem(item);
   *
   * await utilityNetwork.load();
   * console.log("utilityNetwork loaded? ", utilityNetwork.loadStatus);
   */
  static fromPortalItem(params: NetworkFromPortalItemParameters): Promise<UtilityNetwork | null | undefined>;
  constructor(properties?: NetworkProperties);
  /** The full network definition, accessible only when the network is loaded. */
  accessor dataElement: NetworkDataElementJSON | null | undefined;
  /** The physical dataset name of the network as defined in the backend database. Accessible only when the network is loaded. */
  get datasetName(): string | null;
  /**
   * Returns the root feature service url which this network is part of.
   *
   * @example `https://utilitynetwork.esri.com/server/rest/services/NapervilleElectric/FeatureServer/`
   */
  get featureServiceUrl(): string;
  /** The full extent of the network, defined from the service territory used to create the network. */
  get fullExtent(): Extent | null | undefined;
  set fullExtent(value: ExtentProperties | null | undefined);
  /**
   * The version of the geodatabase of the feature service data. Read
   * the [Overview of versioning](https://doc.esri.com/en/arcgis-pro/latest/help/data/geodatabases/overview/overview-of-versioning-in-arcgis-pro.html) topic for more details
   * about this capability.
   */
  accessor gdbVersion: string | null | undefined;
  /**
   * The historic moment to query. If historicMoment is not specified, the query
   * will apply to the current features.
   */
  get historicMoment(): Date | null | undefined;
  set historicMoment(value: (Date | number | string) | null | undefined);
  /** Random unique id (UUID) to identify a network as defined in the webmap spec. Generated during sharing of the webmap. */
  accessor id: string;
  /** The layer id of the network. */
  get layerId(): number;
  /**
   * The full url to the network layer id as defined in the webmap spec.
   * e.g. `https://utilitynetwork.esri.com/server/rest/services/NapervilleElectric/FeatureServer/17` (where 17 is the layer id of the network)
   */
  accessor layerUrl: string;
  /**
   * Indicates whether the network instance has loaded. When `true`,
   * all the properties of the object can be accessed.
   *
   * @default false
   */
  get loaded(): boolean;
  /**
   * Returns the url of network server.
   *
   * @example `https://utilitynetwork.esri.com/server/rest/services/NapervilleElectric/UtilityNetworkServer/`
   */
  get networkServiceUrl(): string;
  /**
   * Contains the url and IDs of the utility network rules, subnetworks, and dirty areas tables or layers.
   *
   * @example
   * // Print out the dirty areas layer url in the utility network
   * view.when(async () => {
   *   // Check if the webmap contains utility networks
   *   if(webmap?.utilityNetworks?.length > 0) {
   *     // Assigns the utility network at index 0
   *     utilityNetwork = webmap.utilityNetworks.at(0);
   *
   *     // Load the utility network
   *     await utilityNetwork.load();
   *
   *     // Print the dirty areas layer url and id
   *     console.log(`Dirty areas layer id: ${utilityNetwork.networkSystemLayers.dirtyAreasLayerId}`);
   *     console.log(`Dirty areas layer url: ${utilityNetwork.networkSystemLayers.dirtyAreasLayerUrl}`);
   *   }
   * });
   */
  get networkSystemLayers(): NetworkSystemLayers | null;
  /** The portal user owner of the network. This portal user can perform administrative actions against the network. */
  get owner(): string | null;
  /** Converts url to a url object */
  get parsedUrl(): UrlObject;
  /**
   * The schema version of the network. Each version of the network introduces new features and capabilities.
   * e.g. A utility network created with ArcGIS Pro 2.8 will have a schema generation version 5. While a UN created with ArcGIS Pro 2.6 will be version 4.
   *
   * @see [Learn more about network schema versions](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/utility-network-dataset-administration.htm)
   */
  get schemaGeneration(): number | null;
  accessor sourceJSON: any;
  /** The spatial reference of the network, defined at the creation of the network, usually from the service territory class. */
  get spatialReference(): SpatialReference;
  set spatialReference(value: SpatialReferenceProperties);
  /** The name of the network as defined in the webmap spec. Represents the layer name of the network layer defined while sharing the webmap. */
  accessor title: string;
  /**
   * The type of the dataset. Returns "utility" if the object represents a utility network or "trace" in case the network is a trace network.
   *
   * @default "utility"
   */
  get type(): "utility" | "trace";
  /**
   * The network consists of sources (classes) and each source has a unique Id.
   * These source Ids are used to perform traversal in the network topology.
   * The trace end points are not aware of layers and only returns sources of results.
   * This method returns the layerId for given a source Id. Used as a helper method to process trace results.
   *
   * @param sourceId - The id of the source.
   * @returns The layer id.
   */
  getLayerIdBySourceId(sourceId: number): number | null | undefined;
  /**
   * Groups network elements by their layerId.
   * Returns a list containing the objectIds within each layer.
   *
   * @param elements - Array of network elements.
   * @returns Array of objects containing layerId and objectIds.
   */
  getObjectIdsFromElements(elements: NetworkElement[]): LayerInfo[];
  /**
   * Returns the layer ID for a given network source ID.
   *
   * @param layerId - The id of the layer.
   * @returns The source corresponding network source ID, if one exists.
   */
  getSourceIdByLayerId(layerId: number): number | null | undefined;
  /**
   * Triggers the loading of the network instance.
   *
   * Fully loads the network definition and all related objects (e.g. trace configurations)
   *
   * @returns Resolves when the Network is [loaded](https://developers.arcgis.com/javascript/latest/references/core/networks/Network/#loaded).
   */
  load(): Promise<this>;
  /**
   * Named trace configurations allow you to add and store complex traces in a network that can be shared across an organization through web maps and consumed by web and field applications.
   * This method returns a list of [NamedTraceConfiguration](https://developers.arcgis.com/javascript/latest/references/core/networks/support/NamedTraceConfiguration/) objects that meet specific search conditions. Used to find existing [named trace configurations](https://pro.arcgis.com/en/pro-app/2.8/help/data/trace-network/about-trace-configurations.htm) in a utility network.
   *
   * @param query - The query parameters that are used to determine which named trace configurations will be returned.
   * @param options - The request options specified by the user in the data request. See [RequestOptions](https://developers.arcgis.com/javascript/latest/references/core/request/types/#RequestOptions) for available properties.
   * @returns Resolves with an array of named trace configurations filtered based on the query parameters.
   * @since 4.25
   * @example
   * // Initialize the query object with global IDs of the named trace configurations to query.
   * const query = {
   *   globalIds: ["5dbb5a13-ab2f-452d-bfcb-6f98154ccb9d", "cf568e46-f200-486c-adb1-d008a3da0ed1"],
   * }
   *
   * // Query the utility network named trace configurations
   * // and filter the results by the query object.
   * const namedTraceConfigurations = await utilityNetwork.queryNamedTraceConfigurations(query);
   *
   * // Print the named trace configurations to the console.
   * console.log(namedTraceConfigurations)
   * @example
   * // Calling this method without parameters returns all named trace configurations in the utility network.
   * const namedTraceConfigurations = await utilityNetwork.queryNamedTraceConfigurations({});
   *
   * // Print all the named trace configurations to the console.
   * console.log(namedTraceConfigurations);
   */
  queryNamedTraceConfigurations(query: QueryNamedTraceConfigurationsParametersProperties, options?: RequestOptions | null | undefined): Promise<NamedTraceConfiguration[]>;
  /**
   * Whenever the network is edited or modified, the network and its features become out of date in the [network topology](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/about-network-topology.htm). Validating the network topology maintains consistency and up-to-date content between the feature editing space and network topology space.
   * Validating a network topology may include all or a subset of the [dirty areas layer](https://developers.arcgis.com/javascript/latest/references/core/networks/Network/#networkSystemLayers) present in the network.
   *
   * @param props - The parameters that are used to validate the network topology.
   * @param options - The request options specified by the user in the data request. See [RequestOptions](https://developers.arcgis.com/javascript/latest/references/core/request/types/#RequestOptions) for available properties.
   * @returns Resolves with the results returned from validating network topology.
   * @since 4.26
   * @example
   * const extent = new Extent({
   *   xmin: 470789.0888,
   *   ymin: 3597733.2051,
   *   xmax: 531454.2759999996,
   *   ymax: 3639864.802100001,
   *   spatialReference: { wkid: 26911, latestWkid: 26911 }
   * });
   *
   * const validationResult = await network.submitTopologyValidationJob({
   *   validateArea: extent,
   *   validationType: "rebuild",
   *   validationSet: [
   *     {
   *       sourceId: 4134325151,
   *       globalIds: ["{7865BAA6-ED9C-4346-9F72-894A49E10C73}"]
   *     }
   *   ]
   * });
   */
  submitTopologyValidationJob(props: ValidateTopologyProperties, options?: RequestOptions | null | undefined): Promise<TopologyValidationJobInfo | null | undefined>;
  /**
   * Whenever the network is edited or modified, the network and its features become out of date in the [network topology](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/about-network-topology.htm). Validating the network topology maintains consistency and up-to-date content between the feature editing space and network topology space.
   * Validating a network topology may include all or a subset of the [dirty areas layer](https://developers.arcgis.com/javascript/latest/references/core/networks/Network/#networkSystemLayers) present in the network.
   *
   * @param props - The parameters that are used to validate the network topology.
   * @param options - The request options specified by the user in the data request. See [RequestOptions](https://developers.arcgis.com/javascript/latest/references/core/request/types/#RequestOptions) for available properties.
   * @returns Resolves with the results returned from validating network topology.
   * @since 4.26
   * @example
   * const extent = new Extent({
   *   xmin: 470789.0888,
   *   ymin: 3597733.2051,
   *   xmax: 531454.2759999996,
   *   ymax: 3639864.802100001,
   *   spatialReference: { wkid: 26911, latestWkid: 26911 }
   * });
   *
   * const result = await network.validateTopology({
   *   validateArea: extent
   * });
   */
  validateTopology(props: ValidateTopologyProperties, options?: RequestOptions | null | undefined): Promise<ValidateNetworkTopologyResult>;
}
declare const NetworkSuperclass: typeof Loadable & typeof MultiOriginJSONSupportMixin

export interface NetworkFromPortalItemParameters {
  /**
   * The object representing an ArcGIS
   * Online or ArcGIS Enterprise portal item from which to load the network.
   */
  portalItem: PortalItem;
}