import type Accessor from "../../core/Accessor.js";
import type SpatialReference from "../../geometry/SpatialReference.js";
import type UtilityNetwork from "../../networks/UtilityNetwork.js";
import type UNTraceConfiguration from "../../networks/support/UNTraceConfiguration.js";
import type TraceLocation from "../../rest/networks/support/TraceLocation.js";
import type TraceResult from "../../rest/networks/support/TraceResult.js";
import type MapView from "../../views/MapView.js";
import type { ResultType } from "../../networks/support/jsonTypes.js";
import type { TraceType } from "../../networks/support/typeUtils.js";

export interface UtilityNetworkTraceAnalysisViewModelProperties extends Partial<Pick<UtilityNetworkTraceAnalysisViewModel, "utilityNetwork" | "view">> {}

/**
 * Object used to execute a custom trace.
 *
 * @since 4.34
 */
export interface TraceConfigurationParameters {
  /** The collection of trace configuration properties. Depending on the trace type, some of the trace configuration properties are required. */
  traceConfiguration: UNTraceConfiguration;
  /** The trace type. This specifies the core algorithm that will be run to analyze the network. */
  traceType: TraceType;
  /** The desired out [SpatialReference](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/) of the trace. */
  outSpatialReference?: SpatialReference;
  /**
   * To perform the trace analytic, users can optionally supply a list of locations in forms of globalIds (UUID) and terminals. These locations indicate starting points and barriers.
   * A [starting point](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/starting-points.htm) is set on network features to define the location in the network where a trace begins. Most traces require one or more starting points to be defined. [Barriers](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/barriers.htm) are used in traces, export subnetwork operations, and update subnetwork operations to mark the locations to stop tracing.
   * Use barriers to represent a location in the network beyond which the trace cannot travel.
   */
  traceLocations?: TraceLocation[];
  /**
   * The types of results to return for the trace.
   *
   * @since 5.0
   */
  resultTypes?: ResultType[];
}

/**
 * Object used to execute a trace using a named trace configuration.
 *
 * @since 4.32
 */
export interface NamedTraceConfigurationParameters {
  /** The globalId of the named trace configuration. */
  namedTraceConfigurationGlobalId: string;
  /** The desired out [SpatialReference](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/) of the trace. */
  outSpatialReference?: SpatialReference;
  /**
   * To perform the trace analytic, users can optionally supply a list of locations in forms of globalIds (UUID) and terminals. These locations indicate starting points and barriers.
   * A [starting point](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/starting-points.htm) is set on network features to define the location in the network where a trace begins. Most traces require one or more starting points to be defined. [Barriers](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/barriers.htm) are used in traces, export subnetwork operations, and update subnetwork operations to mark the locations to stop tracing.
   * Use barriers to represent a location in the network beyond which the trace cannot travel.
   */
  traceLocations?: TraceLocation[];
}

export type UtilityNetworkTraceAnalysisViewModelExecutionError = "trace-error";

export type UtilityNetworkTraceAnalysisViewModelLoadError = "no-user-type-extension" | "no-utility-network" | "no-view" | "sceneView-not-supported";

export type UtilityNetworkTraceAnalysisViewModelState = "disabled" | "executing" | "loading" | "ready";

/**
 * Provides the logic for the UtilityNetworkTraceAnalysis component.
 *
 * @deprecated since version 5.0. Use [UtilityNetworkTraceAnalysis](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetworkTraceAnalysis/).
 * @since 4.32
 * @see [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/)
 */
export default class UtilityNetworkTraceAnalysisViewModel extends Accessor {
  constructor(properties?: UtilityNetworkTraceAnalysisViewModelProperties);
  /** Displays execution errors. */
  get executionError(): UtilityNetworkTraceAnalysisViewModelExecutionError | null | undefined;
  /** Displays an error if loading fails. */
  get loadError(): UtilityNetworkTraceAnalysisViewModelLoadError | null | undefined;
  /** The viewModel's state. */
  get state(): UtilityNetworkTraceAnalysisViewModelState;
  /** Determines the utility network to use. */
  accessor utilityNetwork: UtilityNetwork | null | undefined;
  /** The view from which the widget will operate. */
  accessor view: MapView | null | undefined;
  /**
   * Method used to execute a trace using a named trace configuration.
   *
   * @param parameters - The parameters used to execute a trace based using named trace configurations.
   * @returns When resolved, returns the trace results which could include elements, function results or aggregated geometries.
   * @example
   * const traceLocations = [
   *  {
   *      type: "starting-point",
   *      globalId: "{699C9FDB-3B39-46DC-90D2-13553F3C6694}",
   *      percentAlong: 0.05,
   *  },
   *  {
   *      type: "barrier",
   *      globalId: "{8E99EB07-3BA0-4D7D-A1C0-4D69F5487470}",
   *      percentAlong: 0.7
   *  },
   * ];
   * const traceResult = await traceAnalysisViewModel.executeNamedTraceConfiguration({
   *     namedTraceConfigurationGlobalId: "{E43E4D2C-E191-4547-AFB8-392860694392}",
   *     traceLocations: traceLocations
   * });
   */
  executeNamedTraceConfiguration(parameters: NamedTraceConfigurationParameters): Promise<TraceResult>;
  /**
   * Executes a trace using custom trace parameters and returns trace results.
   *
   * @param parameters - The parameters used to execute a custom trace.
   * @returns When resolved, returns the trace results which could include elements, function results or aggregated geometries.
   * @example
   * const traceConfiguration = new UNTraceConfiguration({
   *   domainNetworkName: "ElectricDistribution",
   *   tierName: "Medium Voltage Radial",
   *   subnetworkName: "RMT001",
   *   conditionBarriers: [
   *     {
   *       name: "Operational Device Status",
   *       type: "networkAttribute",
   *       operator: "equal",
   *       value: 1,
   *       combineUsingOr: false,
   *       isSpecificValue: true,
   *     },
   *   ],
   * });
   *
   * const traceResults = await traceAnalysisViewModel.executeTraceConfiguration({
   *   traceConfiguration,
   *   traceType: "subnetwork",
   * });
   */
  executeTraceConfiguration(parameters: TraceConfigurationParameters): Promise<TraceResult>;
}