// @ts-nocheck
import { Observable } from "rxjs";
import { SuggestionEventType } from "../../utils/enums";
import { SuggestionEventTypesMap } from "../data/suggestion-events.data.model";
import { CommitSuggestionConfig, EnableSuggestionModeConfig, RegisterTargetConfig, Suggestion, SuggestionGetSuggestionsFilter } from "../data/suggestion.data.model";

export declare class SuggestionElement {

  /**
   * Turn on suggestion mode for this user/session and (optionally) register
   * the onTargetEditStart / onTargetEditCommit callbacks the SDK invokes
   * during the auto-detect edit lifecycle.
   *
   * Re-calling with a new config replaces the previous callbacks.
   */
  enableSuggestionMode: (config?: EnableSuggestionModeConfig) => void;

  /**
   * Turn off suggestion mode and clear any registered callbacks.
   */
  disableSuggestionMode: () => void;

  /**
   * Synchronous read of the current enable flag.
   */
  isSuggestionModeEnabled: () => boolean;

  /**
   * Reactive enable-flag stream; deduplicated.
   */
  isSuggestionModeEnabled$: () => Observable<boolean>;

  /**
   * Register a getter that returns the current value of a tagged target.
   * Required for non-primitive (wrapper) targets — the SDK calls this on
   * focus to snapshot the pre-edit value, and again on commit for the diff.
   *
   * The getter must reflect edit-time state (typically read from the DOM),
   * not the persisted customer state. See `RegisterTargetConfig`.
   */
  registerTarget: <T = unknown>(config: RegisterTargetConfig<T>) => void;

  /**
   * Drop the registered getter for a target.
   */
  unregisterTarget: (targetId: string) => void;

  /**
   * Manually capture the current value as the snapshot for a target.
   * Use for non-focusable elements (custom widgets, virtualized rows)
   * where the auto-focus snapshot does not fire.
   */
  startSuggestion: (targetId: string) => void;

  /**
   * Programmatically commit a suggestion. Resolves with the new annotation id.
   * Rejects with one of: INVALID_CONFIG, MODE_NOT_SUGGESTING,
   * TARGET_NOT_REGISTERED, NO_GETTER_FOR_COMPLEX, NO_CHANGE_TO_SUGGEST,
   * SNAPSHOT_FAILED.
   */
  commitSuggestion: <T = unknown>(config: CommitSuggestionConfig<T>) => Promise<{ id: string }>;

  /**
   * Synchronous read of all suggestions on the current document, optionally filtered.
   */
  getSuggestions: (filter?: SuggestionGetSuggestionsFilter) => Suggestion[];

  /**
   * Reactive variant of getSuggestions. Re-emits on every annotation change,
   * deduplicated via the SDK's standard distinct-until-changed comparator.
   */
  getSuggestions$: (filter?: SuggestionGetSuggestionsFilter) => Observable<Suggestion[]>;

  /**
   * Newest pending suggestion for a target, or null. Convenience for
   * pending-overlay UX patterns where each input shows the proposed
   * value while a suggestion is awaiting resolution.
   */
  getPendingSuggestion: <T = unknown>(targetId: string) => Suggestion<T> | null;

  /**
   * Reactive variant of getPendingSuggestion.
   */
  getPendingSuggestion$: <T = unknown>(targetId: string) => Observable<Suggestion<T> | null>;

  /**
   * Subscribe to a suggestion event. Customers call `.subscribe(handler)`
   * on the returned Observable. Event names: 'suggestionCreated',
   * 'suggestionApproved', 'suggestionRejected', 'suggestionStale',
   * 'targetEditStart', 'targetEditCommit'.
   */
  on: <T extends SuggestionEventType>(action: T) => Observable<SuggestionEventTypesMap[T]>;

  constructor();

  /**
   * Turn on suggestion mode for this user/session and (optionally) register
   * the onTargetEditStart / onTargetEditCommit callbacks the SDK invokes
   * during the auto-detect edit lifecycle.
   *
   * Re-calling with a new config replaces the previous callbacks.
   */
  private _enableSuggestionMode;

  /**
   * Turn off suggestion mode and clear any registered callbacks.
   */
  private _disableSuggestionMode;

  /**
   * Synchronous read of the current enable flag.
   */
  private _isSuggestionModeEnabled;

  /**
   * Reactive enable-flag stream; deduplicated.
   */
  private _isSuggestionModeEnabled$;

  /**
   * Register a getter that returns the current value of a tagged target.
   * Required for non-primitive (wrapper) targets — the SDK calls this on
   * focus to snapshot the pre-edit value, and again on commit for the diff.
   *
   * The getter must reflect edit-time state (typically read from the DOM),
   * not the persisted customer state. See `RegisterTargetConfig`.
   */
  private _registerTarget;

  /**
   * Drop the registered getter for a target.
   */
  private _unregisterTarget;

  /**
   * Manually capture the current value as the snapshot for a target.
   * Use for non-focusable elements (custom widgets, virtualized rows)
   * where the auto-focus snapshot does not fire.
   */
  private _startSuggestion;

  /**
   * Programmatically commit a suggestion. Resolves with the new annotation id.
   * Rejects with one of: INVALID_CONFIG, MODE_NOT_SUGGESTING,
   * TARGET_NOT_REGISTERED, NO_GETTER_FOR_COMPLEX, NO_CHANGE_TO_SUGGEST,
   * SNAPSHOT_FAILED.
   */
  private _commitSuggestion;

  /**
   * Synchronous read of all suggestions on the current document, optionally filtered.
   */
  private _getSuggestions;

  /**
   * Reactive variant of getSuggestions. Re-emits on every annotation change,
   * deduplicated via the SDK's standard distinct-until-changed comparator.
   */
  private _getSuggestions$;

  /**
   * Newest pending suggestion for a target, or null. Convenience for
   * pending-overlay UX patterns where each input shows the proposed
   * value while a suggestion is awaiting resolution.
   */
  private _getPendingSuggestion;

  /**
   * Reactive variant of getPendingSuggestion.
   */
  private _getPendingSuggestion$;

  /**
   * Subscribe to a suggestion event. Customers call `.subscribe(handler)`
   * on the returned Observable. Event names: 'suggestionCreated',
   * 'suggestionApproved', 'suggestionRejected', 'suggestionStale',
   * 'targetEditStart', 'targetEditCommit'.
   */
  private _on;
}
