import { ClickEvent, TouchStartEvent } from "../runtime/touch"
import type { ClickEvent as ClickEventType, TouchStartEvent as TouchStartEventType } from "../runtime/touch"
import { type ElementStyle, type ContainerStyle, type Style, ContainerElement, type DrawableStyle, type UINodeChild, type ChildrenFn, type OnLayoutCallback, type BaseStyle, type AnimateStyle, type Color } from "./UINode"

export type UIButtonStyle = ElementStyle & DrawableStyle & ContainerStyle & { rippleColor?: Color | "default" }

export interface UIButton {
  readonly type: "button",

  style: Style<this, UIButtonStyle & { onPressed?: DrawableStyle & BaseStyle & { duration?: number } }>,
  animateTo: AnimateStyle<this, DrawableStyle & BaseStyle>,
  animateFrom: AnimateStyle<this, DrawableStyle & BaseStyle>

  onClick(callback: (ev: ClickEventType<UIButton>) => void): this,
  onTouchStart(callback: (ev: TouchStartEventType<UIButton>) => void): this,
  isPressed(): boolean,

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

  onLayout(onLayout: OnLayoutCallback): this

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

  readonly children: UINodeChild[],
}


class ButtonElement extends ContainerElement<"button"> {

  readonly clickListeners: any[] = []
  readonly touchStartListeners: any[] = []

  onClick (callback: any): this {
    this.clickListeners.push(callback)
    return this
  }
  _emitClick(pointerId: number, clientX: number, clientY: number) {
    const touchEvent = new ClickEvent(clientX, clientY, pointerId)
    touchEvent.target = this
    for (let callback of this.clickListeners) {
      callback(touchEvent)
    }
    return null
  }

  onTouchStart (callback: any): this {
    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
  }

  isPressed(): boolean {
    if (!this._id) return false
    return _creatorUI.isButtonPressed(this._id)
  }
}

export function UIButton(): UIButton;
export function UIButton(children: UINodeChild[] | ChildrenFn): UIButton;
export function UIButton(style: UIButtonStyle): UIButton;
export function UIButton(style: UIButtonStyle, children: UINodeChild[]): UIButton;
export function UIButton(...args: [] | [UINodeChild[] | ChildrenFn | UIButtonStyle] | [UIButtonStyle, children: UINodeChild[] | ChildrenFn]): UIButton {
  if (args.length === 0) {
    return new ButtonElement("button", {}, [])
  } else if (args.length === 1) {
    if (Array.isArray(args[0]) || typeof args[0] === "function") {
      return new ButtonElement("button", {}, args[0])
    } else {
      return new ButtonElement("button", args[0], [])
    }
  } else {
    return new ButtonElement("button", args[0], args[1])
  }
}
