import type Graphic from "../../Graphic.js";
import type EsriError from "../../core/Error.js";
import type SharedTemplateMetadata from "../../editing/sharedTemplates/SharedTemplateMetadata.js";
import type FormTemplate from "../../form/FormTemplate.js";
import type Mesh from "../../geometry/Mesh.js";
import type Point from "../../geometry/Point.js";
import type Polygon from "../../geometry/Polygon.js";
import type Polyline from "../../geometry/Polyline.js";
import type SubtypeGroupLayer from "../../layers/SubtypeGroupLayer.js";
import type CatalogFootprintLayer from "../../layers/catalog/CatalogFootprintLayer.js";
import type KnowledgeGraphSublayer from "../../layers/knowledgeGraph/KnowledgeGraphSublayer.js";
import type FeatureTemplate from "../../layers/support/FeatureTemplate.js";
import type SubtypeSublayer from "../../layers/support/SubtypeSublayer.js";
import type Attachments from "../Attachments.js";
import type BatchAttributeForm from "../BatchAttributeForm.js";
import type FeatureForm from "../FeatureForm.js";
import type FeatureTemplates from "../FeatureTemplates.js";
import type SketchViewModel from "../Sketch/SketchViewModel.js";
import type { EditableLayerUnion } from "../../layers/types.js";
import type { ObjectId } from "../../views/types.js";
import type { SketchViewModelEvents } from "../Sketch/SketchViewModel.js";

/**
 * Configurations used for setting the layer's editable preferences within the Editor.
 *
 * @since 5.0
 */
export interface LayerInfo {
  /**
   * The associated layer containing the fields to edit.
   *
   * @since 5.0
   */
  layer: EditorLayerUnion;
  /**
   * A template that defines the feature's form content. Use this when setting the fields for editing.
   *
   * @since 5.0
   */
  formTemplate?: FormTemplate;
  /**
   * Indicates whether to enable editing on the layer.
   *
   * @default true
   * @since 5.0
   */
  enabled?: boolean;
  /**
   * Indicates whether to enable the ability to create new features.
   *
   * @default true
   * @since 5.0
   */
  addEnabled?: boolean;
  /**
   * Indicates whether to enable the ability to update existing features.
   *
   * @default true
   * @since 5.0
   */
  updateEnabled?: boolean;
  /**
   * Indicates whether to enable the ability to delete features.
   *
   * @default true
   * @since 5.0
   */
  deleteEnabled?: boolean;
  /**
   * Indicates whether to enable or disable geometry updates.
   *
   * @default true
   * @since 5.0
   */
  geometryUpdatesEnabled?: boolean;
  /**
   * Indicates whether to enable or disable attribute updates from the feature's form.
   *
   * @default true
   * @since 5.0
   */
  attributeUpdatesEnabled?: boolean;
  /**
   * _(Since 4.26)_ Indicates whether to enable or disable attachments while creating features. Support for this is dependent upon whether this operation is supported on the [FeatureLayer.capabilities.operations](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#capabilities).
   *
   * @default true
   * @since 5.0
   */
  attachmentsOnCreateEnabled?: boolean;
  /**
   * _(Since 4.26)_ Indicates whether to enable or disable attachments while updating existing features. Support for this is dependent upon whether `update` or `delete` operations are supported on the [FeatureLayer.capabilities](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#capabilities).
   *
   * > [!WARNING]
   * >
   * > The Editor will not display attachment file names if it is displaying image types. These images must have resize support within its corresponding [FeatureLayer.capabilities](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#capabilities), ie. `FeatureLayer.capabilities.attachment.supportsResize` is `true`. Attachment types, other than images, will display an icon and its corresponding file name.
   *
   * @default true
   * @since 5.0
   */
  attachmentsOnUpdateEnabled?: boolean;
}

/**
 * This object provides required and optional properties needed when creating a new feature.
 *
 * @since 5.0
 */
export interface CreationInfo {
  /**
   * The associated layer for newly-created feature.
   *
   * @since 5.0
   */
  layer: EditorLayerUnion;
  /**
   * The associated [Mesh](https://developers.arcgis.com/javascript/latest/references/core/geometry/Mesh/) geometry for the newly-created feature. This property is only applicable when editing [scene layers](https://developers.arcgis.com/javascript/latest/references/core/layers/SceneLayer/).
   *
   * @since 5.0
   */
  geometryToPlace?: Mesh | null;
  /**
   * The initial feature used when you begin creating features.
   *
   * @since 5.0
   */
  initialFeature?: Graphic;
  /**
   * The maximum amount of feature to create in one batch editing operation.
   *
   * @since 5.0
   */
  maxFeatures?: number;
  /**
   * The associated feature template used to create new features.
   *
   * @since 5.0
   */
  template?: FeatureTemplate | SharedTemplateMetadata;
}

/** @since 5.0 */
export type EditorLayerUnion = Exclude<EditableLayerUnion, SubtypeGroupLayer | CatalogFootprintLayer> | SubtypeSublayer | KnowledgeGraphSublayer;

/** @since 5.0 */
export type State = "add-association-select-layer" | "add-association-select-feature" | "add-association-create-association" | "adding-attachment" | "awaiting-feature-creation-info" | "awaiting-feature-to-create" | "awaiting-feature-to-update" | "awaiting-update-feature-candidate" | "choosing-key-feature" | "creating-features" | "disabled" | "drawing-splitter-geometry" | "editing-attributes" | "editing-attachment" | "editing-existing-feature" | "editing-features" | "ready" | "reviewing-features" | "viewing-selection-list";

/** @since 5.0 */
export type AttachmentsProperties = Partial<Pick<Attachments, "displayType" | "capabilities">>;

/** @since 5.1 */
export type BatchAttributeFormProperties = Partial<Pick<BatchAttributeForm, "groupDisplay">>;

/** @since 5.0 */
export type FeatureFormProperties = Partial<Pick<FeatureForm, "groupDisplay">>;

/** @since 5.0 */
export type FeatureTemplatesProperties = Partial<Pick<FeatureTemplates, "groupBy" | "visibleElements" | "enableListScroll">>;

/** @since 5.0 */
export type SketchProperties = Partial<Pick<SketchViewModel, "defaultUpdateOptions" | "pointSymbol" | "polygonSymbol" | "polylineSymbol" | "updateOnGraphicClick">>;

/**
 * Set this to customize any supporting Editor widget's default behavior. Specific properties can be adjusted in the [Attachments](https://developers.arcgis.com/javascript/latest/references/core/widgets/Attachments/), [FeatureForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/), and [FeatureTemplates](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/) widgets. In addition, it is possible to update specific properties within the [SketchViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/Sketch/SketchViewModel/).
 *
 * @since 5.0
 */
export interface SupportingWidgetDefaults {
  /**
   * An object containing properties specific for customizing the [Attachments](https://developers.arcgis.com/javascript/latest/references/core/widgets/Attachments/) widget.
   *
   * @deprecated since 5.1.
   * @since 5.0
   */
  attachments?: AttachmentsProperties;
  /**
   * An object containing properties specific for customizing the [BatchAttributeForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/BatchAttributeForm/) widget.
   *
   * @since 5.1
   */
  batchAttributeForm?: BatchAttributeFormProperties;
  /**
   * An object containing properties specific for customizing the [FeatureForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) widget.
   *
   * @deprecated since 5.1.
   * @since 5.0
   */
  featureForm?: FeatureFormProperties;
  /**
   * An object containing properties specific for customizing the [FeatureTemplates](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/) widget.
   *
   * @since 5.0
   */
  featureTemplates?: FeatureTemplatesProperties;
  /**
   * An object containing properties specific for customizing the [Sketch](https://developers.arcgis.com/javascript/latest/references/core/widgets/Sketch/) widget.
   *
   * @since 5.0
   */
  sketch?: SketchProperties;
}

/** @since 5.0 */
export interface FailedOperation {
  /**
   * The read-only error message.
   *
   * @since 5.0
   */
  readonly error: EsriError;
}

/** @since 5.0 */
export type CreateFeaturesWorkflowStep = Extract<State, "awaiting-feature-creation-info" | "creating-features" | "adding-attachment" | "editing-attachment">;

/** @since 5.0 */
export type CreateFeatureState = "create-new" | "update-pending";

/** @since 5.0 */
export type MergeFeaturesWorkflowStep = "choosing-key-feature";

/** @since 5.0 */
export type UpdateFeaturesWorkflowStep = "editing-features";

/** @since 5.0 */
export type SplitFeatureWorkflowStep = "drawing-splitter-geometry" | "reviewing-features";

/** @since 5.0 */
export type UpdateWorkflowStep = Extract<State, "awaiting-feature-to-update" | "awaiting-update-feature-candidate" | "editing-existing-feature" | "adding-attachment" | "editing-attachment">;

/** @since 5.0 */
export interface CancelWorkflowOptions {
  /**
   * The returned Error object.
   *
   * @since 5.0
   */
  error?: EsriError;
  /**
   * Indicates whether to force cancel the active workflow.
   *
   * @since 5.0
   */
  force?: boolean;
  /**
   * Indicates whether to display a prompt indicating canceling the active workflow.
   *
   * @since 5.0
   */
  emitCancelEvent?: boolean;
}

/**
 * This object provides information required when updating a set of features.
 *
 * @since 5.0
 */
export interface FeatureInfo {
  /**
   * The layer containing features.
   *
   * @since 5.0
   */
  layer: EditorLayerUnion;
  /**
   * The object identifiers for features being edited
   *
   * @since 5.0
   */
  objectIds: ObjectId[];
}

/** @since 5.0 */
export interface EditorSketchEventBase {
  /**
   * The layer currently being edited.
   *
   * @since 5.0
   */
  layer: EditorLayerUnion;
}

/** @since 5.0 */
export interface EditorSketchCreateEvent extends EditorSketchEventBase {
  /** @since 5.0 */
  type: "sketch-create";
  /**
   * Detailed information returned within the "sketch-create" event.
   *
   * @since 5.0
   */
  detail: SketchViewModelEvents["create"];
}

/** @since 5.0 */
export interface EditorSketchUpdateEvent extends EditorSketchEventBase {
  /** @since 5.0 */
  type: "sketch-update";
  /**
   * Detailed information returned within the "sketch-update" event.
   *
   * @since 5.0
   */
  detail: SketchViewModelEvents["update"];
}

/** @since 5.0 */
export type SplitterGeometry = Point | Polyline | Polygon;

/** @since 5.0 */
export type SplitterGeometryType = "point" | "polyline" | "polygon";