import type Graphic from "../../Graphic.js";
import type EsriError from "../../core/Error.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 SubtypeSublayer from "../../layers/support/SubtypeSublayer.js";
import type Attachments from "../Attachments.js";
import type FeatureForm from "../FeatureForm.js";
import type FeatureTemplates from "../FeatureTemplates.js";
import type SketchViewModel from "../Sketch/SketchViewModel.js";
import type { AnyEditingTemplateInfo } from "../../editing/types.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. */
export interface LayerInfo {
  /**
   * Indicates whether to enable the ability to create new features.
   *
   * @default true
   */
  addEnabled?: 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/api-reference/esri-layers-FeatureLayer.html#capabilities).
   *
   * @default true
   */
  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/api-reference/esri-layers-FeatureLayer.html#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/api-reference/esri-layers-FeatureLayer.html#capabilities), ie. `FeatureLayer.capabilities.attachment.supportsResize` is `true`. Attachment types, other than images, will display an icon and its corresponding file name.
   *
   * @default true
   */
  attachmentsOnUpdateEnabled?: boolean;
  /**
   * Indicates whether to enable or disable attribute updates from the feature's form.
   *
   * @default true
   */
  attributeUpdatesEnabled?: boolean;
  /**
   * Indicates whether to enable the ability to delete features.
   *
   * @default true
   */
  deleteEnabled?: boolean;
  /**
   * Indicates whether to enable editing on the layer.
   *
   * @default true
   */
  enabled?: boolean;
  /** A template that defines the feature's form content. Use this when setting the fields for editing. */
  formTemplate?: FormTemplate;
  /**
   * Indicates whether to enable or disable geometry updates.
   *
   * @default true
   */
  geometryUpdatesEnabled?: boolean;
  /** The associated layer containing the fields to edit. */
  layer: EditorLayerUnion;
  /**
   * Indicates whether to enable the ability to update existing features.
   *
   * @default true
   */
  updateEnabled?: boolean;
}

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

export type EditorLayerUnion = Exclude<EditableLayerUnion, SubtypeGroupLayer | CatalogFootprintLayer> | SubtypeSublayer | KnowledgeGraphSublayer;

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";

export type AttachmentsProperties = Partial<Pick<Attachments, "displayType" | "capabilities">>;

export type FeatureFormProperties = Partial<Pick<FeatureForm, "groupDisplay">>;

export type FeatureTemplatesProperties = Partial<Pick<FeatureTemplates, "groupBy" | "visibleElements" | "enableListScroll">>;

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/api-reference/esri-widgets-Attachments.html), [FeatureForm](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm.html), and [FeatureTemplates](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureTemplates.html) widgets. In addition, it is possible to update specific properties within the [SketchViewModel](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Sketch-SketchViewModel.html). */
export interface SupportingWidgetDefaults {
  /** An object containing properties specific for customizing the [Attachments](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Attachments.html) widget. */
  attachments?: AttachmentsProperties;
  /** An object containing properties specific for customizing the [FeatureForm](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm.html) widget. */
  featureForm?: FeatureFormProperties;
  /** An object containing properties specific for customizing the [FeatureTemplates](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureTemplates.html) widget. */
  featureTemplates?: FeatureTemplatesProperties;
  /** An object containing properties specific for customizing the [Sketch](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Sketch.html) widget. */
  sketch?: SketchProperties;
}

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

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

export type CreateFeatureState = "create-new" | "update-pending";

export type MergeFeaturesWorkflowStep = "choosing-key-feature";

export type UpdateFeaturesWorkflowStep = "editing-features";

export type SplitFeatureWorkflowStep = "drawing-splitter-geometry" | "reviewing-features";

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

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

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

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

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

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

export type SplitterGeometry = Point | Polyline | Polygon;

export type SplitterGeometryType = "point" | "polyline" | "polygon";