/// <reference path="../../index.d.ts" />
import type UtilityNetwork from "@arcgis/core/networks/UtilityNetwork.js";
import type ValidateNetworkTopologyResult from "@arcgis/core/rest/networks/support/ValidateNetworkTopologyResult.js";
import type MapView from "@arcgis/core/views/MapView.js";
import type { PublicLitElement as LitElement } from "@arcgis/lumina";
import type { ArcgisReferenceElement } from "../types.js";
import type { T9nMeta } from "@arcgis/lumina/controllers";

/** Component state when validation is unavailable because the component cannot run. */
export interface Disabled {
  type: "disabled";
}

/** Component state while utility network topology validation is currently running. */
export interface Executing {
  type: "executing";
}

/** Component state while component dependencies are loading. */
export interface Loading {
  type: "loading";
}

/** Component state when component dependencies are loaded and validation can execute. */
export interface Ready {
  type: "ready";
}

/** Component state after validation completes successfully. */
export interface Success {
  type: "success";
  message: string;
}

/** Component state when validation or setup encounters an error. */
export interface ValidateNetworkTopologyError {
  /**
   * The type of error the component has encountered:
   *
   * - `error-disable-component`: The component is disabled because the component could not find a utility network in the map.
   * - `error-disable-execute`: The component cannot run validation because the user lacks permissions or the dirty areas layer is missing from the map.
   * - `error-info`: Some other error occurred while running validation. The error is displayed in the component.
   */
  type: "error-disable-component" | "error-disable-execute" | "error-info";
  /** Additional information about the error the component has encountered. */
  message: string;
}

/** The extent options for network topology validation. */
export type ExtentOption = "current" | "entire";

/** The current component workflow state. */
export type State = Disabled | Executing | Loading | Ready | Success | ValidateNetworkTopologyError;

/**
 * ## Overview
 *
 * The Utility Network Validate Network Topology component validates dirty areas in a utility network after edits have been made.
 * It provides an interface to choose a utility network (if applicable), choose the [extent](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-utility-network-validate-network-topology/#extentToValidate) to validate, and perform validation.
 * If successful, the result of the validation is available as [result](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-utility-network-validate-network-topology/#result).
 *
 * ## Validation requirements
 *
 * - The component only supports a 2D [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/).
 * - The utility network must be [stored in the map](https://developers.arcgis.com/javascript/latest/references/core/WebMap/#utilityNetworks) and the network topology must be enabled.
 * - The active portal user must have the required user type extension to validate a network topology.
 * - Validation fails in cases such as: no dirty areas in the target extent, inability to acquire a version lock, or insufficient permissions on the version.
 *
 * > [!WARNING]
 * >
 * > The Utility Network Validate Network Topology component does not support proxied feature services or feature services that utilize stored credentials.
 *
 * ## Examples
 *
 * This component can be used slotted into an [arcgis-map](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/):
 *
 * ```html
 * <arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310">
 *   <arcgis-utility-network-validate-network-topology slot="top-right"></arcgis-utility-network-validate-network-topology>
 * </arcgis-map>
 * ```
 *
 * Alternatively, this component can be used outside of a map by providing a [referenceElement](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-utility-network-validate-network-topology/#referenceElement):
 *
 * ```html
 * <calcite-shell>
 *   <calcite-shell-panel slot="panel-start" position="start" width-scale="l">
 *     <arcgis-utility-network-validate-network-topology reference-element="#map-element"></arcgis-utility-network-validate-network-topology>
 *   </calcite-shell-panel>
 *   <arcgis-map id="map-element" item-id="471eb0bf37074b1fbb972b1da70fb310"></arcgis-map>
 * </calcite-shell>
 * ```
 *
 * <video src="https://developers.arcgis.com/javascript/latest/assets/references/components/utility-network-validate-network-topology/validate-topology-example.webm" autoplay loop muted playsInline></video>
 *
 * @since 5.1
 * @see [Network topology](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/about-network-topology.htm)
 * @see [Validate a network topology](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/validate-a-network-topology.htm)
 * @see [Dirty areas](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/dirty-areas-in-a-utility-network.htm)
 */
export abstract class ArcgisUtilityNetworkValidateNetworkTopology extends LitElement {
  /** @internal */
  protected _messages: {
      componentLabel: string;
      actions: { validateTopology: string; };
      errors: {
          cannotAcquireVersionLock: string;
          noAdvancedEditingUserTypeExtension: string;
          noDirtyAreasInExtent: string;
          noDirtyAreasLayer: string;
          noUtilityNetwork: string;
          noUtilityNetworks: string;
          noUtilityNetworkServiceUserTypeExtension: string;
          noView: string;
          operationOnlyAllowedByOwner: string;
          sceneViewNotSupported: string;
          utilityNetworkLoadFailed: string;
      };
      info: { validateCanceled: string; };
      input: {
          selectExtent: {
              label: string;
              options: {
                  currentExtent: string;
                  entireExtent: string;
              };
          };
          selectUtilityNetwork: { label: string; };
      };
      status: {
          executing: string;
          success: string;
      };
  } & T9nMeta<{
      componentLabel: string;
      actions: { validateTopology: string; };
      errors: {
          cannotAcquireVersionLock: string;
          noAdvancedEditingUserTypeExtension: string;
          noDirtyAreasInExtent: string;
          noDirtyAreasLayer: string;
          noUtilityNetwork: string;
          noUtilityNetworks: string;
          noUtilityNetworkServiceUserTypeExtension: string;
          noView: string;
          operationOnlyAllowedByOwner: string;
          sceneViewNotSupported: string;
          utilityNetworkLoadFailed: string;
      };
      info: { validateCanceled: string; };
      input: {
          selectExtent: {
              label: string;
              options: {
                  currentExtent: string;
                  entireExtent: string;
              };
          };
          selectUtilityNetwork: { label: string; };
      };
      status: {
          executing: string;
          success: string;
      };
  }>;
  /**
   * A function to run before utility network topology validation starts.
   *
   * The function is awaited before the [@arcgisValidateNetworkTopologyStart](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-utility-network-validate-network-topology/#event-arcgisValidateNetworkTopologyStart)
   * event is emitted and before the validation request is sent.
   * If the function rejects its Promise, validation does not start and the component displays an error. If the Promise was rejected with an [Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error), the component displays the error.
   *
   * @internal
   * @example
   * ```js
   * const validateNetworkTopologyElement = document.querySelector("arcgis-utility-network-validate-network-topology");
   * validateNetworkTopologyElement.beforeValidateNetworkTopologyStart = async () => await doAsyncWork();
   * ```
   */
  accessor beforeValidateNetworkTopologyStart: (() => Promise<void>) | undefined;
  /**
   * When true, the component is visually withdrawn and cannot receive user interaction.
   *
   * @default false
   */
  accessor disabled: boolean;
  /**
   * Specifies the area to validate.
   *
   * Use `"current"` to validate the current view extent. Use `"entire"` to validate the utility network's full extent.
   *
   * @default "current"
   */
  accessor extentToValidate: ExtentOption;
  /**
   * When true, hides the utility network selector.
   *
   * The selector is also hidden when the map has one utility network.
   *
   * @default false
   */
  accessor hideUtilityNetworkSelect: boolean;
  /** The component's default label. */
  accessor label: string | undefined;
  /**
   * Replace localized message strings with your own strings.
   *
   * _**Note**: Individual message keys may change between releases._
   */
  accessor messageOverrides: {
      componentLabel?: string | undefined;
      actions?: { validateTopology?: string | undefined; } | undefined;
      errors?: {
          cannotAcquireVersionLock?: string | undefined;
          noAdvancedEditingUserTypeExtension?: string | undefined;
          noDirtyAreasInExtent?: string | undefined;
          noDirtyAreasLayer?: string | undefined;
          noUtilityNetwork?: string | undefined;
          noUtilityNetworks?: string | undefined;
          noUtilityNetworkServiceUserTypeExtension?: string | undefined;
          noView?: string | undefined;
          operationOnlyAllowedByOwner?: string | undefined;
          sceneViewNotSupported?: string | undefined;
          utilityNetworkLoadFailed?: string | undefined;
      } | undefined;
      info?: { validateCanceled?: string | undefined; } | undefined;
      input?: {
          selectExtent?: {
              label?: string | undefined;
              options?: {
                  currentExtent?: string | undefined;
                  entireExtent?: string | undefined;
              } | undefined;
          } | undefined;
          selectUtilityNetwork?: { label?: string | undefined; } | undefined;
      } | undefined;
      status?: {
          executing?: string | undefined;
          success?: string | undefined;
      } | undefined;
  };
  /**
   * By assigning the `id` attribute of the Map or Scene component to this property, you can position a child component anywhere in the DOM while still maintaining a connection to the Map or Scene.
   *
   * @see [Associate components with a Map or Scene component](https://developers.arcgis.com/javascript/latest/programming-patterns/#associate-components-with-a-map-or-scene-component)
   */
  accessor referenceElement: ArcgisReferenceElement | string | undefined;
  /**
   * The result returned from the most recent successful utility network topology validation.
   * This value is cleared when clicking the "Validate" action.
   */
  accessor result: ValidateNetworkTopologyResult | undefined;
  /** The current component state. */
  get state(): State;
  /**
   * The utility network to validate.
   *
   * If not provided, the component uses the first utility network stored in the map. When the map contains multiple
   * utility networks and the selector is visible, the user can change this value from the component UI.
   */
  accessor utilityNetwork: UtilityNetwork | undefined;
  /**
   * The target [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/).
   *
   * The component only supports 2D map views.
   */
  accessor view: MapView | undefined;
  /** Emitted when the component associated with a map or scene view is ready to be interacted with. */
  readonly arcgisReady: import("@arcgis/lumina").TargetedEvent<this, void>;
  /**
   * Fires after a validation workflow ends.
   *
   * This event fires after validation succeeds, fails, or is canceled by preventing the
   * [@arcgisValidateNetworkTopologyStart](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-utility-network-validate-network-topology/#event-arcgisValidateNetworkTopologyStart) event.
   */
  readonly arcgisValidateNetworkTopologyEnd: import("@arcgis/lumina").TargetedEvent<this, void>;
  /**
   * Fires before the validation request is sent.
   *
   * This event can be prevented with `event.preventDefault()` to cancel validation.
   *
   * @example
   * ```js
   * const validateNetworkTopologyElement = document.querySelector("arcgis-utility-network-validate-network-topology");
   * validateNetworkTopologyElement.addEventListener("arcgisValidateNetworkTopologyStart", (event) => {
   *   event.preventDefault();
   * });
   * ```
   */
  readonly arcgisValidateNetworkTopologyStart: import("@arcgis/lumina").TargetedEvent<this, void>;
  readonly "@eventTypes": {
    arcgisReady: ArcgisUtilityNetworkValidateNetworkTopology["arcgisReady"]["detail"];
    arcgisValidateNetworkTopologyEnd: ArcgisUtilityNetworkValidateNetworkTopology["arcgisValidateNetworkTopologyEnd"]["detail"];
    arcgisValidateNetworkTopologyStart: ArcgisUtilityNetworkValidateNetworkTopology["arcgisValidateNetworkTopologyStart"]["detail"];
  };
}