import type { VideoPlayer } from "../runtime/media"
import { _bumpNavEpoch, _navSupported, _setCurrent, Presentable, type PresentOptions } from "./presentable"
import { Element, type BaseStyle, type DrawableStyle, type ElementStyle, type UIElementBase } from "./UINode"

export type UIVideoStyle = ElementStyle & DrawableStyle & { objectFit?: "cover" | "contain" | "fill" }

/** A video surface showing a `VideoPlayer`'s output — embeddable in a screen AND
 *  fullscreen-presentable (`open()`), with seamless promotion between the two. */
export interface UIVideo extends UIElementBase<UIVideoStyle, DrawableStyle & BaseStyle> {
  readonly type: "video",
  /** The player driving this surface (playback control lives on it). */
  player: VideoPlayer

  /** Show fullscreen as the current destination. Promotion: if this video is mounted in a screen,
   *  the SAME native player moves fullscreen — playback uninterrupted; a pop moves it back. */
  open(options?: PresentOptions): void
  /** Dismiss if this is the visible destination. */
  close(): void
  /** Became the visible destination. */
  onOpen(callback: () => void): this
  /** Stopped being the visible destination. */
  onClose(callback: () => void): this
  /** Hardware/system back while current. */
  onBackPressed(callback: () => void): this
}

class VideoElement extends Element<"video"> implements Presentable {
  private _playerId: number
  private _player: VideoPlayer
  constructor(style: any, player: VideoPlayer) {
    super("video", style)
    this._player = player
    this._playerId = (player as any)._id
  }

  get player() {
    return this._player
  }

  // ---- Presentable (docs/navigation-presentable-plan.md) ----
  readonly ol: (() => void)[] = []
  readonly cl: (() => void)[] = []
  _backButtonCallback?: () => void
  private _vd?: object

  /** @internal wire descriptor — type "videoView" (distinct from the "video" node type). */
  _viewDesc(): object {
    return this._vd ??= { type: "videoView", node: this, _p: this }
  }

  open(options?: PresentOptions): void {
    if (!_navSupported()) {
      throw new Error("Fullscreen video is not supported on this host (requires _creatorUI.openView)")
    }
    _bumpNavEpoch()
    _creatorUI.openView!(this._viewDesc(), options?.transition ?? "none")
    _setCurrent(this)
  }
  close(): void {
    _bumpNavEpoch()
    if (_navSupported()) _creatorUI.closeView!()
    if (Presentable.current === this) _setCurrent(null)
  }
  onOpen(callback: () => void): this {
    this.ol.push(callback)
    return this
  }
  onClose(callback: () => void): this {
    this.cl.push(callback)
    return this
  }
  onBackPressed(callback: () => void): this {
    this._backButtonCallback = callback
    return this
  }
}

/** Create a video node showing `player`'s output. */
export function UIVideo(player: VideoPlayer): UIVideo
/** @deprecated Style as the first argument is legacy — use chained `.style({...})`. */
export function UIVideo(style: UIVideoStyle, player: VideoPlayer): UIVideo
export function UIVideo(...args: [VideoPlayer] | [UIVideoStyle, VideoPlayer]): UIVideo {
    if (args.length === 1) {
    return new VideoElement({}, args[0])
  } else {
    return new VideoElement(args[0], args[1])
  }
}
