import type Polyline from "../../../geometry/Polyline.js";
import type NetworkElement from "./NetworkElement.js";
import type { JSONSupport } from "../../../core/JSONSupport.js";
import type { AssociationType } from "../../../networks/support/typeUtils.js";
import type { NetworkElementProperties } from "./NetworkElement.js";
import type { PolylineProperties } from "../../../geometry/Polyline.js";

export interface AssociationProperties extends Partial<Pick<Association, "associationType" | "errorCode" | "errorMessage" | "globalId" | "isContentVisible" | "percentAlong" | "status">> {
  /** The from side network element of the association. Contains the globalid, network source, and terminal. */
  fromNetworkElement?: NetworkElementProperties | null;
  /** The synthesized [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html) geometry created between the two network elements. */
  geometry?: PolylineProperties;
  /** The to side network element of the association. Contains the globalid, network source, and terminal. */
  toNetworkElement?: NetworkElementProperties | null;
}

/**
 * The utility network associations model connectivity, containment and structure relations between assets.
 * An `Association` connects two network elements, the "From" and "To", and order of the association matter.
 * This class defines an association and its basic properties.
 *
 * @since 4.25
 * @see [QueryAssociationsResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-networks-support-QueryAssociationsResult.html)
 * @see [queryAssociations](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-networks-queryAssociations.html)
 * @see [QueryAssociationsParameters](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-networks-support-QueryAssociationsParameters.html)
 * @example
 * // Define the QueryAssociationsParameters
 * const queryAssociationsParameters = new QueryAssociationsParameters({
 *   types: ["containment", "attachment", "junction-edge-from-connectivity"],
 *   elements: [
 *     {
 *       networkSourceId: 2,
 *       globalId: "{46B3FA19-2237-4D38-A7CF-AA34C3T40420}",
 *       objectId: 44,
 *       terminalId: 1,
 *       assetGroupCode: 1,
 *       assetTypeCode: 1
 *     },
 *     {
 *       networkSourceId: 9,
 *       globalId: "{321C0089-1165-42D9-K45B-ED91B1A40500}",
 *       objectId: 45,
 *       terminalId: 1,
 *       assetGroupCode: 13,
 *       assetTypeCode: 441
 *     }
 *  ]
 * });
 *
 * // Query associations, and assign the query result to a variable `associations`
 * const associations = await queryAssociations(networkServiceUrl, queryAssociationsParameters);
 *
 * // Print out the first association
 * console.log(associations[0]);
 */
export default class Association extends JSONSupport {
  constructor(properties?: AssociationProperties);
  /** The type of association. Associations that could be synthesized are `attachment`, `connectivity` or `containment`. There are also non-spatial associations that were introduced in schema version 4. Those will be added post 4.20 */
  accessor associationType: AssociationType;
  /** Error code returned from the server for a failed associations query. */
  accessor errorCode: number | null | undefined;
  /** Message returned from the server for a failed associations query. */
  accessor errorMessage: string | null | undefined;
  /** The from side network element of the association. Contains the globalid, network source, and terminal. */
  get fromNetworkElement(): NetworkElement | null | undefined;
  set fromNetworkElement(value: NetworkElementProperties | null | undefined);
  /** The synthesized [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html) geometry created between the two network elements. */
  get geometry(): Polyline;
  set geometry(value: PolylineProperties);
  /** The globalId (UUID) of the association record, uniquely identifies this association row. */
  accessor globalId: string | null | undefined;
  /** Specifies the content visibility on the map. */
  accessor isContentVisible: boolean | null | undefined;
  /**
   * This double parameter of value of 0-1 indicates a percentage along the line of where the trace location is placed. Applicable to line features only.
   *
   * @example
   * Line feature with objectId 100 with 2 midspan junctions (j1,j2). The line feature has 3 edge network elements
   * F-j1, j1-j2 and j2-T.
   *
   *                                        OID=100
   *                                F------j1------j2------T
   *
   * F-j1  (objectId=100, positionFrom=0, positionTo=0.33)
   * j1-j2 (objectId=100, positionFrom=0.33, positionTo=0.66)
   * j2-T  (objectId=100, positionFrom=0.66, positionTo=1)
   *
   * When percentAlong is 0.5 (50%) the starting location will be placed on the middle edge (j1-j2)
   *
   *                                        OID=100
   *                                F------j1---x--j2------T
   *
   * When percentAlong is 0.1 (10%) the starting location will be placed on the first edge (F-j1)
   *
   *                                        OID=100
   *                                F-x----j1------j2------T
   */
  accessor percentAlong: number | null | undefined;
  /**
   * Indicates the type of association a feature or object participates in, the role the network feature plays in the association relationship, and any properties that are set.
   *
   * @see [ArcGIS Pro: Association status attribute](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/association-status-attribute.htm)
   */
  accessor status: number | null | undefined;
  /** The to side network element of the association. Contains the globalid, network source, and terminal. */
  get toNetworkElement(): NetworkElement | null | undefined;
  set toNetworkElement(value: NetworkElementProperties | null | undefined);
}