/**
 * A base viewer for BPMN 2.0 diagrams.
 *
 * Have a look at {@link Viewer}, {@link NavigatedViewer} or {@link Modeler} for
 * bundles that include actual features.
 *
 */
export default class BaseViewer extends Diagram {
  /**
   * @param options The options to configure the viewer.
   */
  constructor(options?: BaseViewerOptions);

  importXML: (xml: string, bpmnDiagram?: ModdleElement | string) => Promise<ImportXMLResult>;
  importDefinitions: (definitions: ModdleElement, bpmnDiagram?: ModdleElement | string) => Promise<ImportDefinitionsResult>;
  open: (bpmnDiagramOrId: ModdleElement | string) => Promise<OpenResult>;
  saveXML: (options?: SaveXMLOptions) => Promise<SaveXMLResult>;
  saveSVG: () => Promise<SaveSVGResult>;

  /**
   * Return modules to instantiate with.
   *
   * @return The modules.
   */
  getModules(): ModuleDeclaration[];

  /**
   * Register an event listener.
   *
   * Remove an event listener via {@link BaseViewer#off}.
   *
   *
   * @param events The event(s) to listen to.
   * @param callback The callback.
   * @param that Value of `this` the callback will be called with.
   */
  on<T>(events: string | string[], callback: EventBusEventCallback<T>, that?: any): any;

  /**
   * Register an event listener.
   *
   * Remove an event listener via {@link BaseViewer#off}.
   *
   *
   * @param events The event(s) to listen to.
   * @param priority The priority with which to listen.
   * @param callback The callback.
   * @param that Value of `this` the callback will be called with.
   */
  on<T>(
    events: string | string[],
    priority: number,
    callback: EventBusEventCallback<T>,
    that?: any
  ): any;

  /**
   * Remove an event listener.
   *
   * @param events The event(s).
   * @param callback The callback.
   */
  off(events: string | string[], callback?: Function): void;

  /**
   * Attach the viewer to an HTML element.
   *
   * @param parentNode The parent node to attach to.
   */
  attachTo(parentNode: HTMLElement): void;

  /**
   * Get the definitions model element.
   *
   * @return The definitions model element.
   */
  getDefinitions(): ModdleElement;

  /**
   * Detach the viewer.
   *
   * @fires BaseViewer#DetachEvent
   */
  detach(): void;
}

type EventBusEventCallback<T> = import('diagram-js/lib/core/EventBus').EventBusEventCallback<T>;
type ModuleDeclaration = import('didi').ModuleDeclaration;
type Moddle = import('./model/Types').Moddle;
type ModdleElement = import('./model/Types').ModdleElement;
type ModdleExtension = import('./model/Types').ModdleExtension;

export type BaseViewerOptions = {
    width?: number | string;
    height?: number | string;
    position?: string;
    container?: string | HTMLElement;
    moddleExtensions?: ModdleExtensions;
    additionalModules?: ModuleDeclaration[];
} & Record<string, any>;

export type ModdleElementsById = Record<string, ModdleElement>;

export type ModdleExtensions = {
    [key: string]: import("./model/Types").ModdleExtension;
};

export type ImportXMLResult = {
    warnings: string[];
};

export type ImportXMLError = ImportXMLResult & Error;
export type ImportDefinitionsResult = ImportXMLResult;
export type ImportDefinitionsError = ImportXMLError;
export type OpenResult = ImportXMLResult;
export type OpenError = ImportXMLError;

export type SaveXMLOptions = {
    format?: boolean;
    preamble?: boolean;
};

export type SaveXMLResult = {
    xml?: string;
    error?: Error;
};

export type SaveSVGResult = {
    svg: string;
};

export type ImportParseStartEvent = {
    xml: string;
};

export type ImportParseCompleteEvent = {
    error?: ImportXMLError;
    definitions?: ModdleElement;
    elementsById?: ModdleElementsById;
    references?: ModdleElement[];
    warnings: string[];
};

export type ImportDoneEvent = {
    error?: ImportXMLError;
    warnings: string[];
};

export type SaveXMLStartEvent = {
    definitions: ModdleElement;
};

export type SaveXMLDoneEvent = SaveXMLResult;

export type SaveSVGDoneEvent = {
    error?: Error;
    svg: string;
};

import Diagram from 'diagram-js';
