import type {
  ActivateOptions,
  EngineStats,
  EngineInspection,
  ExportedJoanConfig,
  FieldName,
  JoanEngineOptions,
  JoanGlyphEngine,
  Palette,
  PixelSwitchRecipe,
  PixelShapeName,
  PixelSwitchName,
  ResumeOptions,
  SetSpriteOptions,
  SignalPayload,
  SpriteName,
  SpriteRecipe,
  TransitionDetail,
  TransitionToOptions,
  JoanGlyphEventName,
  JoanGlyphEvent,
} from "./index.js";

export const JOAN_GLYPH_TAG_NAME: "joan-glyph";

export class JoanGlyphElement extends HTMLElement {
  static readonly observedAttributes: readonly string[];
  readonly canvas: HTMLCanvasElement;
  readonly engine: JoanGlyphEngine | null | undefined;

  connectedCallback(): void;
  disconnectedCallback(): void;
  attributeChangedCallback(
    name: string,
    oldValue: string | null,
    newValue: string | null,
  ): void;
  readOptions(): JoanEngineOptions;
  readNonErrorPalette(): Palette | null;
  setSprite(
    sprite: SpriteName | SpriteRecipe,
    options?: SetSpriteOptions,
  ): JoanGlyphEngine | undefined;
  setProgress(value: number): JoanGlyphEngine | undefined;
  setNonErrorPalette(palette: Palette | null): JoanGlyphEngine | undefined;
  setSeed(seed: string | number): JoanGlyphEngine | undefined;
  setResolution(size: number): JoanGlyphEngine | undefined;
  setField(field: FieldName): JoanGlyphEngine | undefined;
  useRecipeFields(): JoanGlyphEngine | undefined;
  setPixelShape(shape: PixelShapeName): JoanGlyphEngine | undefined;
  setPixelSwitch(
    pixelSwitch: PixelSwitchName | PixelSwitchRecipe,
  ): JoanGlyphEngine | undefined;
  setOptions(options: Partial<JoanEngineOptions>): JoanGlyphEngine | undefined;
  configure(
    options?: Partial<JoanEngineOptions>,
    configureOptions?: { strict?: boolean },
  ): JoanGlyphEngine | undefined;
  setAudioLevel(value: number): JoanGlyphEngine | undefined;
  activate(options?: ActivateOptions): JoanGlyphEngine | undefined;
  resume(options?: ResumeOptions): JoanGlyphEngine | undefined;
  play(): JoanGlyphEngine | undefined;
  pause(): JoanGlyphEngine | undefined;
  toggle(): JoanGlyphEngine | undefined;
  renderOnce(time?: number): EngineStats | undefined;
  transitionTo(
    sprite: SpriteName | SpriteRecipe,
    options?: TransitionToOptions,
  ): Promise<TransitionDetail> | undefined;
  whenTransitionComplete(options?: {
    signal?: AbortSignal;
  }): Promise<TransitionDetail> | undefined;
  inspect(): EngineInspection | undefined;
  on<K extends JoanGlyphEventName>(
    type: K,
    listener: (event: JoanGlyphEvent<K>) => void,
    options?: boolean | AddEventListenerOptions,
  ): (() => void) | undefined;
  exportConfig(): ExportedJoanConfig | undefined;
  signal(type: string, payload?: SignalPayload): JoanGlyphEngine | undefined;
}

export function defineJoanGlyph(
  tagName?: string,
): typeof JoanGlyphElement;

declare global {
  interface HTMLElementTagNameMap {
    "joan-glyph": JoanGlyphElement;
  }
}

export default JoanGlyphElement;
