import type UNTraceConfiguration from "./UNTraceConfiguration.js";

/** @since 5.0 */
export type UtilityNetworkFeatureClassUsageType = "esriUNFCUTDevice" | "esriUNFCUTJunction" | "esriUNFCUTLine" | "esriUNFCUTAssembly" | "esriUNFCUTSubnetLine" | "esriUNFCUTStructureJunction" | "esriUNFCUTStructureLine" | "esriUNFCUTStructureBoundary" | "esriUNFCUTJunctionObject" | "esriUNFCUTEdgeObject" | "esriUNFCUTStructureJunctionObject" | "esriUNFCUTStructureEdgeObject" | "esriUNFCUTCircuit" | "esriUNFCUTCircuitSection" | "esriUNFCUTSubcircuit";

/** @since 5.0 */
export type PolicyType = "esriDPTUnitApportioned" | "esriDPTDefaultValue" | "esriCPTSumValues" | "esriCPTDefaultValue";

/**
 * Uniquely identifies an element by network source ID and global ID.
 *
 * @since 4.34
 */
export interface UnitIdentifier {
  /**
   * The element's network source ID.
   *
   * @since 5.0
   */
  sourceId: number;
  /**
   * The element's global ID.
   *
   * @since 5.0
   */
  globalId: string;
}

/**
 * A range of unit identifiers in a container feature or object's containment hierarchy.
 *
 * @since 4.34
 */
export interface UnitRange {
  /**
   * The unit offset in the grouped object.
   *
   * @since 5.0
   */
  firstUnit: number;
  /**
   * The last unit in the unit identifier range.
   *
   * @since 5.0
   */
  lastUnit: number;
  /**
   * Whether the unit identifier range is a gap, i.e., is not utilized.
   *
   * @since 5.0
   */
  isGap: boolean;
  /**
   * The object consuming the unit identifiers in this range.
   *
   * @since 5.0
   */
  content?: UnitIdentifier | null;
}

/**
 * Results returned from the [CircuitManager.export()](https://developers.arcgis.com/javascript/latest/references/core/networks/CircuitManager/#export) method.
 *
 * @since 4.34
 */
export interface CircuitExportResult {
  /**
   * The name of the exported circuit.
   *
   * @since 5.0
   */
  circuitName: string;
  /**
   * The location of the exported circuit JSON file.
   *
   * @since 5.0
   */
  url: string;
  /**
   * Indicates if the circuit has been logically deleted.
   *
   * @since 5.0
   */
  circuitHasBeenDeleted: boolean;
  /**
   * Indicates if the export was successful.
   *
   * @since 5.0
   */
  success: boolean;
  /**
   * Optional error information if the export failed.
   *
   * @since 5.0
   */
  error?: CircuitExportResultError;
}

/** @since 5.0 */
export interface CircuitExportResultError {
  /**
   * Error message.
   *
   * @since 5.0
   */
  message: string;
  /**
   * Extended error code.
   *
   * @since 5.0
   */
  extendedCode: number;
  /**
   * Additional error details.
   *
   * @since 5.0
   */
  details: string[];
}

/**
 * AssetTypeJSON represents [asset type](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/utility-feature-classification.htm#GUID-A4CCEB96-C4F8-459B-A763-FF6A5791F663).
 * Attribute domains are assigned on the asset type field at the subtype level for each network class. It represents the minor classification of the utility network classes.
 *
 * @since 5.0
 */
export interface AssetTypeJSON {
  /**
   * The unique code for the asset type.
   *
   * @since 5.0
   */
  assetTypeCode: number;
  /**
   * The name of the asset type.
   *
   * @since 5.0
   */
  assetTypeName?: string;
  /**
   * Indicates if terminal configurations are supported for the asset type.
   *
   * @since 5.0
   */
  isTerminalConfigurationSupported?: boolean;
  /**
   * The terminal configuration ID associated with the asset type, if applicable.
   *
   * @since 5.0
   */
  terminalConfigurationId?: number;
  /**
   * The connectivity policy applied to the asset type.
   *
   * @since 5.0
   */
  connectivityPolicy?: string;
}

/**
 * AssetGroupJSON represents the [asset group](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/utility-feature-classification.htm#GUID-A4CCEB96-C4F8-459B-A763-FF6A5791F663).
 * The asset group is the subtype field and represents the major classification of utility network classes.
 *
 * @since 5.0
 */
export interface AssetGroupJSON {
  /**
   * The unique code for the asset group.
   *
   * @since 5.0
   */
  assetGroupCode: number;
  /**
   * The asset group name.
   *
   * @since 5.0
   */
  assetGroupName?: string;
  /**
   * An array of asset types associated with the asset group.
   *
   * @since 5.0
   */
  assetTypes: AssetTypeJSON[];
}

/** @since 5.0 */
export interface CircuitSourceJSON {
  /**
   * The layer id of the point layer.
   *
   * @since 5.0
   */
  layerId: number;
  /**
   * The network source id of the layer.
   *
   * @since 5.0
   */
  sourceId: number;
  /**
   * The usage type of the edge source.
   *
   * @since 5.0
   */
  utilityNetworkFeatureClassUsageType: UtilityNetworkFeatureClassUsageType;
}

/**
 * JunctionSourceJSON represents the point layers that participate in the utility network service.
 *
 * @since 5.0
 */
export interface NetworkSourceJSON extends CircuitSourceJSON {
  /**
   * The asset group attribute values for the point layer.
   *
   * @since 5.0
   */
  assetGroups: AssetGroupJSON[];
  /**
   * Supported properties for the edge source.
   *
   * @since 5.0
   */
  supportedProperties: string[];
}

/**
 * Describes a domain network in a utility network data element.
 *
 * @since 4.34
 */
export interface DomainNetworkJSON {
  /**
   * The name of the domain network.
   *
   * @since 5.0
   */
  domainNetworkName: string;
  /**
   * Indicates if this domain network is a structure network.
   *
   * @since 5.0
   */
  isStructureNetwork: boolean;
  /**
   * Indicates if this domain network is a telecom domain network.
   *
   * @since 5.0
   */
  isTelecomNetwork: boolean;
  /**
   * An array of network source objects that represent the sources of junction features.
   *
   * @since 5.0
   */
  junctionSources: NetworkSourceJSON[];
  /**
   * An array of network source objects that represent the sources of edge features.
   *
   * @since 5.0
   */
  edgeSources: NetworkSourceJSON[];
  /**
   * An array of tier definitions used to organize the network into hierarchical levels. Null if no tiers are defined, e.g., a telecom domain network.
   *
   * @since 5.0
   */
  tiers?: TierJSON[] | null;
  /**
   * The layer ID of the subnetwork layer. Null if no subnetwork layer is defined, e.g., a telecom domain network.
   *
   * @since 5.0
   */
  subnetworkLayerId?: number | null;
  /**
   * An array of circuit source objects for telecom networks.
   *
   * @since 5.0
   */
  circuitSources?: CircuitSourceJSON[] | null;
  /**
   * Circuit properties for telecom networks.
   *
   * @since 5.0
   */
  circuitProperties?: CircuitPropertiesJSON | null;
  /**
   * An array of objects to describe color schemes in a telecom domain network.
   *
   * @since 5.0
   */
  colorSchemes?: ColorSchemeJSON[] | null;
  /**
   * An array of objects describing divide policies for a telecom domain network.
   *
   * @since 5.0
   */
  dividePolicies?: PolicyJSON[] | null;
  /**
   * An array of objects describing combine policies.
   *
   * @since 5.0
   */
  combinePolicies?: PolicyJSON[] | null;
  /**
   * A UNTraceConfiguration object that defines the trace configuration for the domain network.
   *   This configuration includes parameters specific to utility networks.
   *
   * @since 5.0
   */
  traceConfiguration?: UNTraceConfiguration | null;
}

/** @since 5.0 */
export interface CircuitPropertiesJSON {
  /**
   * The type of the property set.
   *
   * @since 5.0
   */
  type: "PropertySet";
  /**
   * The items in the property set.
   *
   * @since 5.0
   */
  propertySetItems: (string | boolean)[];
}

/** @since 5.0 */
export interface ColorSchemeJSON {
  /**
   * The name of the color scheme.
   *
   * @since 5.0
   */
  name: string;
  /**
   * The id of the color scheme.
   *
   * @since 5.0
   */
  id: number;
  /**
   * The group delimiter.
   *
   * @since 5.0
   */
  groupDelimiter: string;
  /**
   * The number of levels in the color scheme.
   *
   * @since 5.0
   */
  levels: number;
  /**
   * An array of objects representing color groups in the color scheme.
   *
   * @since 5.0
   */
  groups: ColorGroupJSON[];
}

/** @since 5.0 */
export interface ColorGroupJSON {
  /**
   * The name of the color group.
   *
   * @since 5.0
   */
  name: string;
  /**
   * The level of the color group.
   *
   * @since 5.0
   */
  level: number;
  /**
   * The delimiter for the color group.
   *
   * @since 5.0
   */
  delimiter: string;
  /**
   * The labels for the color group.
   *
   * @since 5.0
   */
  labels: (string | number)[];
  /**
   * The capacity for the color group.
   *
   * @since 5.0
   */
  capacity: number[];
}

/** @since 5.0 */
export interface PolicyJSON {
  /**
   * The source ID for the policy.
   *
   * @since 5.0
   */
  sourceId: number;
  /**
   * The attribute name for the policy.
   *
   * @since 5.0
   */
  attributeName: string;
  /**
   * The policy type.
   *
   * @since 5.0
   */
  policy: PolicyType;
}

/** @since 5.0 */
export interface TierJSON {
  /**
   * The name of the tier.
   *
   * @since 5.0
   */
  name: string;
}

/** @since 5.0 */
export interface TerminalConfigurationJSON {
  /**
   * The Id that uniquely identifies the terminal configuration.
   *
   * @since 5.0
   */
  terminalConfigurationId: number;
}

/**
 * Contains the full network definition.
 *
 * @since 4.33
 */
export interface NetworkDataElementJSON {
  /**
   * An array of domain networks included in the utility network.
   *
   * @since 5.0
   */
  domainNetworks: DomainNetworkJSON[];
  /**
   * The user identity associated with the network definition.
   *
   * @since 5.0
   */
  userIdentity: string;
  /**
   * The name of the utility network.
   *
   * @since 5.0
   */
  name: string;
  /**
   * The schema generation version number of the utility network.
   *
   * @since 5.0
   */
  schemaGeneration: number;
  /**
   * An array of terminal configuration objects available in the network.
   *
   * @since 5.0
   */
  terminalConfigurations: TerminalConfigurationJSON[];
  /**
   * The layer Id of the feature layer representing service territories within the network.
   *
   * @since 5.0
   */
  serviceTerritoryFeatureLayerId: number;
}

/**
 * ResultTypeJSON specifies the type of results to return after running a trace.
 *
 * @since 5.0
 * @example
 * // Creates a new instance of this class and initializes it with values inputted in json format. A resultTypes object is passed into the resultTypes property.
 * const traceParameters = TraceParameters.fromJSON({
 *    traceConfigurationGlobalId: "{DF22DA8D-6EC0-408B-A8B2-E468EC7DC9BF}",
 *    moment: 1554214441244,
 *    gdbVersion: "SDE.DEFAULT",
 *    resultTypes: [
 *      {
 *        type: "elements",
 *        includeGeometry: false,
 *        includePropagatedValues: false,
 *        networkAttributeNames: [],
 *        diagramTemplateName: "",
 *        resultTypeFields: []
 *      },
 *      {
 *        type: "aggregatedGeometry",
 *        includeGeometry: false,
 *        includePropagatedValues: false,
 *        networkAttributeNames: [],
 *        diagramTemplateName: "",
 *        resultTypeFields: []
 *      }
 *    ],
 *    traceType: "subnetwork"
 *  });
 */
export interface ResultType {
  /**
   * Specifies the return type for the trace. `paths` and `circuits` are reserved for future use.
   *
   * @since 5.0
   */
  type: "elements" | "aggregatedGeometry" | "paths" | "circuits";
  /**
   * Specifies whether to return geometry values in resultTypes.
   *
   * @since 5.0
   */
  includeGeometry: boolean;
  /**
   * Specifies whether to return propagated values in resultTypes.
   *
   * @since 5.0
   */
  includePropagatedValues: boolean;
  /**
   * Specifies the network attribute names.
   *
   * @since 5.0
   */
  networkAttributeNames: string[];
  /**
   * Specifies the name of a predefined Diagram Template.
   *
   * @since 5.0
   */
  diagramTemplateName: string;
  /**
   * Specifies the types of output fields that can be generated from geoprocessing tools.
   *
   * @since 5.0
   */
  resultTypeFields: Object[];
}

/**
 * Specifies the type of results to export for circuits.
 *
 * @since 5.0
 * @example
 * const exportCircuitProps = {
 *   circuitNames: ["TESTCIRCUIT"],
 *   exportAcknowledgement: false,
 *   resultTypes: [
 *     {
 *       type: "features",
 *       includeGeometry: true,
 *       includeDomainDescriptions: true,
 *       networkAttributeNames: ["Asset group", "Asset type"],
 *       diagramTemplateName: "",
 *       resultTypeFields: [
 *         { networkSourceId: 20, fieldName: "FIRSTUNIT" },
 *         { networkSourceId: 20, fieldName: "LASTUNIT" },
 *       ],
 *     },
 *   ],
 * };
 *
 * const exportResult = await circuitManager.export(exportCircuitProps);
 */
export interface ExportCircuitsResultType {
  /**
   * The return type for the export.
   *
   * @since 5.0
   */
  type: "features" | "connectivity" | "associations" | "circuits";
  /**
   * Whether to include geometry values in the export.
   *
   * @since 5.0
   */
  includeGeometry: boolean;
  /**
   * Specifies whether domain descriptions will be included in the output file
   * to communicate domain mapping for features and connectivity.
   *
   * @since 5.0
   */
  includeDomainDescriptions: boolean;
  /**
   * The network attributes that will be included in the result.
   *
   * @since 5.0
   */
  networkAttributeNames: string[];
  /**
   * The name of a predefined diagram template.
   *
   * @since 5.0
   */
  diagramTemplateName: string;
  /**
   * The feature class and field name values to include in the export.
   *
   * @since 5.0
   */
  resultTypeFields: Record<string, any>[];
}

/**
 * ValidationSetItemJSON represents the set of features and objects to validate.
 *
 * @since 5.0
 * @example
 * const validationResult = await network.submitTopologyValidationJob(
 *   new ValidateNetworkTopologyParameters({
 *     validateArea: extent,
 *     gdbVersion: "sde.DEFAULT",
 *     validationType: "rebuild",
 *     sessionID: "{7865BAA6-ED9C-4346-9F72-894A49E10C73}",
 *     validationSet: [
 *       {
 *         sourceId: 4134325151,
 *         globalIds: ["{7865BAA6-ED9C-4346-9F72-894A49E10C73}"]
 *       }
 *     ]
 *   })
 * );
 *
 * console.log("result: ", validationResult);
 */
export interface ValidationSetItemJSON {
  /**
   * The network source id of the.
   *
   * @since 5.0
   */
  sourceId: number;
  /**
   * An array of globalId strings to validate.
   *
   * @since 5.0
   */
  globalIds: string[];
}