import type FeatureLayer from "../layers/FeatureLayer.js";
import type UtilityNetwork from "./UtilityNetwork.js";
import type Circuit from "./support/Circuit.js";
import type CircuitVerifyResult from "../rest/networks/circuits/support/CircuitVerifyResult.js";
import type { JSONSupport } from "../core/JSONSupport.js";
import type { CircuitExportResult, DomainNetworkJSON } from "./support/jsonTypes.js";
import type { ExportCircuitsParametersProperties } from "../rest/networks/circuits/support/ExportCircuitsParameters.js";
import type { QueryCircuitsParametersProperties } from "../rest/networks/circuits/support/QueryCircuitsParameters.js";
import type { VerifyCircuitsParametersProperties } from "../rest/networks/circuits/support/VerifyCircuitsParameters.js";
import type { UtilityNetworkProperties } from "./UtilityNetwork.js";

export interface CircuitManagerProperties {
  /**
   * An object representing the telecom domain network in the
   * utility network data element.
   */
  telecomDomainNetwork?: DomainNetworkJSON;
  /** The [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/) that contains the telecom domain network being managed. */
  utilityNetwork?: UtilityNetworkProperties;
}

/**
 * Describes a start/stop circuit location for circuit queries.
 *
 * @since 4.34
 */
export type QueryCircuitProperties = Pick<QueryCircuitsParametersProperties, "location" | "locationType" | "returnConsumerCircuits">;

export type ExportCircuitsProperties = Pick<ExportCircuitsParametersProperties, "circuitNames" | "exportAcknowledgement" | "resultTypes">;

export type VerifyCircuitsProperties = Pick<VerifyCircuitsParametersProperties, "circuitNames" | "continueOnFailure" | "forceVerify" | "synthesizeGeometries">;

/**
 * A CircuitManager provides access to circuit management capabilities for a telecom domain network
 * in a utility network.
 *
 * @beta
 * @since 4.34
 * @see [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/)
 * @see [UnitIdentifierManager](https://developers.arcgis.com/javascript/latest/references/core/networks/UnitIdentifierManager/)
 * @see [Telecom domain network](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/telecom-domain-networks.htm)
 * @example
 * const utilityNetwork = new UtilityNetwork({
 *   layerUrl: "https://host.com/arcgis/rest/services/Test/FeatureServer/0",
 * });
 *
 * await utilityNetwork.load();
 *
 * const domainNetworks = utilityNetwork.dataElement?.domainNetworks;
 * const telecomDomainNetwork = domainNetworks.find((dn) => dn.isTelecomNetwork);
 *
 * const circuitManager = await utilityNetwork.getCircuitManager(telecomDomainNetwork.domainNetworkName);
 */
export default class CircuitManager extends JSONSupport {
  constructor(properties?: CircuitManagerProperties);
  /** A [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) for the telecom domain network's circuit section table. */
  get circuitSectionTable(): FeatureLayer;
  /** A [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) for the telecom domain network's circuit table. */
  get circuitTable(): FeatureLayer;
  /**
   * Returns the root feature service URL which the utility network is part of.
   *
   * @example `https://utilitynetwork.esri.com/server/rest/services/NapervilleElectric/FeatureServer/`
   */
  get featureServiceUrl(): string;
  /**
   * The version of the geodatabase of the feature service data used by the utility network.
   * Read the [Overview of versioning](https://pro.arcgis.com/en/pro-app/latest/help/data/geodatabases/overview/overview-of-versioning-in-arcgis-pro.htm)
   * topic for more details about this capability.
   */
  get gdbVersion(): string | null | undefined;
  /**
   * The utility network's historic moment to query.
   * If this property is not specified, queries will apply to the current features.
   */
  get historicMoment(): Date | null | undefined;
  /**
   * The URL of the network server.
   *
   * @example `https://utilitynetwork.esri.com/server/rest/services/NapervilleElectric/UtilityNetworkServer/`
   */
  get networkServiceUrl(): string;
  /** A [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) for the telecom domain network's subcircuit table. */
  get subcircuitTable(): FeatureLayer;
  /**
   * An object representing the telecom domain network in the
   * utility network data element.
   */
  get telecomDomainNetwork(): DomainNetworkJSON;
  /** The name of the telecom domain network. */
  get telecomDomainNetworkName(): string;
  /** The [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/) that contains the telecom domain network being managed. */
  get utilityNetwork(): UtilityNetwork;
  /**
   * Modifies circuit information for an existing circuit in a telecom domain network.
   * This method replaces the existing circuit definition with the provided circuit.
   * If any properties are excluded from the provided circuit definition, it is removed from the circuit.
   *
   * To alter an existing circuit, the provided [Circuit](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/) must
   * have a valid `globalId` property, else this method will throw an exception.
   *
   * @param circuit - The circuit to be altered.
   * @returns Resolves when the circuit is successfully altered.
   */
  alter(circuit: Circuit): Promise<void>;
  /**
   * Creates a circuit in a telecom domain network.
   *
   * > [!WARNING]
   * >
   * > Circuits created during an active edit session will not be returned by a query until the session has been ended with `stopEditing`.
   *
   * @param circuit - The circuit to create.
   * @returns Resolves when the circuit is successfully created.
   */
  create(circuit: Circuit): Promise<void>;
  /**
   * Logically deletes one or more circuits in a telecom domain network.
   *
   * @param circuitNames - The names of the circuit or circuits to be deleted.
   * @returns Resolves when the specified circuits are successfully deleted.
   */
  delete(circuitNames: string[]): Promise<void>;
  /**
   * Exports feature and connectivity information about provided circuits in a telecom domain network
   * into JSON files for consumption by external systems. Each circuit exported is output to a separate JSON file.
   *
   * @param props - An object specifying configuration settings for the export.
   * @returns Resolves to an object
   *   specifying the export location and status for each circuit.
   */
  export(props: ExportCircuitsProperties): Promise<CircuitExportResult[]>;
  /**
   * Returns a [Circuit](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/) instance
   * with its `circuitManager` property set to the current `CircuitManager` instance.
   *
   * @param circuitName - The name of the `Circuit` instance to create.
   * @param isSectioned - = false - Whether the `Circuit` instance is sectioned.
   * @returns A `Circuit` instance with its `circuitManager` property set to the current `CircuitManager` instance.
   */
  getCircuit(circuitName: string, isSectioned?: boolean): Circuit;
  /**
   * Loads the telecom domain network's circuit section table.
   *
   * @returns Resolves to a loaded [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) for the circuit section table.
   */
  loadCircuitSectionTable(): Promise<FeatureLayer>;
  /**
   * Loads the telecom domain network's circuit table.
   *
   * @returns Resolves to a loaded [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) for the circuit table.
   */
  loadCircuitTable(): Promise<FeatureLayer>;
  /**
   * Loads the telecom domain network's subcircuit table.
   *
   * @returns Resolves to a loaded [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) for the subcircuit table.
   */
  loadSubcircuitTable(): Promise<FeatureLayer>;
  /**
   * Returns the names of circuits in a telecom domain network with specified start/stop locations.
   *
   * > [!WARNING]
   * >
   * > Querying circuits by location is not supported and will fail as of Telecom Domain Network Beta 2.
   *
   * @param props - The start/stop location of the circuits to query.
   * @returns The queried circuit names.
   */
  queryCircuitNames(props: QueryCircuitProperties): Promise<string[]>;
  /**
   * Returns circuits from a telecom domain network that satisfy a specified query.
   * This method accepts two types of input: an array of circuit names, or an object specifying a trace location from
   * which the circuits to query either start or stop.
   *
   * If specifying a trace location: If `returnConsumingCircuits` is false, only the immediate circuits that pass
   * through the specified feature are returned. Otherwise, all the circuits that consume the immediate circuits are returned.
   *
   * > [!WARNING]
   * >
   * > Querying circuits by location is not supported and will fail as of Telecom Domain Network Beta 2.
   *
   * @param input - The names or start/stop location of the circuits to query.
   * @returns The queried circuits.
   */
  queryCircuits(input: string[] | QueryCircuitProperties): Promise<Circuit[]>;
  /**
   * Checks the validity of circuits in a telecom domain network.
   * The operation confirms that a circuit can be traced from the starting location to the stopping location
   * and ensures that circuit sections and subcircuits are properly configured.
   *
   * @param props - An object specifying configuration settings for the verify operation.
   * @returns Resolves to an array of objects specifying the verification status for each circuit.
   */
  verify(props: VerifyCircuitsProperties): Promise<CircuitVerifyResult[]>;
}