import { TouchStartEvent } from "../runtime/touch"
import { ContainerElement, type AnimateStyle, type BaseStyle, type Color, type ContainerStyle, type DrawableStyle, type OnLayoutCallback, type PaddingStyle, type PositionStyle, type Style, type UINodeChild, type ChildrenFn } from "./UINode"


export type UIWidgetStyle = ContainerStyle & DrawableStyle & PaddingStyle & BaseStyle & PositionStyle & {
  // A layer behind the widget that intercepts clicks. "transparent" still intercepts;
  // null removes the layer. A tap on it fires onOverlayTap.
  overlayColor?: Color | null
}


export interface UIWidget {
  readonly type: "widget",
  style: Style<this, UIWidgetStyle>,
  animateTo: AnimateStyle<this, DrawableStyle & BaseStyle & { overlayColor?: Color | null }>
  animateFrom: AnimateStyle<this, DrawableStyle & BaseStyle & { overlayColor?: Color | null }>

  show(): void,
  hide(): void,

  readonly isShow: boolean,

  append(...nodes: UINodeChild[]): UIWidget
  insert(index: number, ...nodes: UINodeChild[]): UIWidget
  remove(...nodes: UINodeChild[]): UIWidget
  setContent(nodes: UINodeChild[] | ChildrenFn): this
  
  readonly children: UINodeChild[],

  onLayout(onLayout: OnLayoutCallback): this
  onTouchStart(callback: (ev: TouchStartEvent<UIWidget>) => void): this,
  onOverlayTap(callback: () => void): this,
  onBackPressed(callback: () => void): this

  setClass(name: string, enabled: boolean): this
  toggleClass(name: string): this
  hasClass(name: string): boolean
  bindClass(name: string, fn: () => boolean): this
}


export class WidgetElement extends ContainerElement<"widget"> {
  scrollable = false as const
  show(): void {
    _creatorUI.showWidget(this) 
  }
  hide(): void {
    _creatorUI.hideWidget(this)
  }
  get isShow(): boolean {
    return this._id !== 0
  }

  _interactive = false
  readonly touchStartListeners: any[] = []
  onTouchStart (callback: any): this {
    this._interactive = true
    this.touchStartListeners.push(callback)
    return this
  }
  _emitTouchStart(pointerId: number, clientX: number, clientY: number): any {
    const touchEvent = new TouchStartEvent(clientX, clientY, pointerId)
    touchEvent.target = this
    for (let callback of this.touchStartListeners) {
      callback(touchEvent)
      if ((touchEvent as any)._trackHandler) {
        return (touchEvent as any)._trackHandler
      }
    }
    return null
  }
  readonly otl: (() => void)[] = []
  onOverlayTap(callback: () => void): this {
    this.otl.push(callback)
    return this
  }

  _backButtonCallback?: () => void
  onBackPressed(callback: any): this {
    this._backButtonCallback = callback
    return this
  }
}


export function UIWidget(): UIWidget;
export function UIWidget(children: UINodeChild[] | ChildrenFn): UIWidget;
export function UIWidget(style: UIWidgetStyle): UIWidget;
export function UIWidget(style: UIWidgetStyle, children: UINodeChild[]): UIWidget;
export function UIWidget(...args: [] | [UINodeChild[] | ChildrenFn | UIWidgetStyle] | [UIWidgetStyle, children: UINodeChild[] | ChildrenFn]): UIWidget {
  if (args.length === 0) {
    return new WidgetElement("widget", {}, [])
  } else if (args.length === 1) {
    if (Array.isArray(args[0]) || typeof args[0] === "function") {
      return new WidgetElement("widget", {}, args[0])
    } else {
      return new WidgetElement("widget", args[0], [])
    }
  } else {
    return new WidgetElement("widget", args[0], args[1])
  }
}