import type { UIContainerStyle } from "./UIContainer"
import { type Style, type AnimateStyle, type UINodeChild, type ChildrenFn, type OnLayoutCallback, ContainerElement } from "./UINode"

export type ScrollStyle = { showScrollbar?: boolean, overscrollMode?: "none" | "absorb" | "default" }

export type UIScrollableStyle = UIContainerStyle & ScrollStyle & { scrollDirection?: "horizontal" | "vertical" }

export interface UIScrollable {
  readonly type: "scrollable",
  style: Style<this, UIScrollableStyle>,
  animateTo: AnimateStyle<this, UIScrollableStyle>,
  animateFrom: AnimateStyle<this, UIScrollableStyle>,
  
  append(...nodes: UINodeChild[]): UIScrollable
  insert(index: number, ...nodes: UINodeChild[]): UIScrollable
  remove(...nodes: UINodeChild[]): UIScrollable
  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

  onScroll(callback: (scrollPosition: number) => void): UIScrollable,
  onScrollRelease(callback: () => void): UIScrollable,
  onOverscroll(callback: (delta: number) => void): UIScrollable

  readonly children: UINodeChild[]
}

class ScrollableElement extends ContainerElement<"scrollable"> {

  readonly osl: any[] = []
  readonly sl: any[] = []
  readonly srl: any[] = []

  get scrollListeners() {
    return this.sl
  }

  onScroll (callback: any): this {
    this.sl.push(callback)
    return this
  }

  onScrollRelease (callback: any): this {
    this.srl.push(callback)
    return this
  }

  onOverscroll (callback: any): this {
    this.osl.push(callback)
    return this
  }
}

export function UIScrollable(): UIScrollable
export function UIScrollable(children: UINodeChild[] | ChildrenFn): UIScrollable
export function UIScrollable(style: UIScrollableStyle): UIScrollable
export function UIScrollable(style: UIScrollableStyle, children: UINodeChild[]): UIScrollable
export function UIScrollable(...args: [] | [UINodeChild[] | ChildrenFn | UIScrollableStyle] | [UIScrollableStyle, children: UINodeChild[] | ChildrenFn]): UIScrollable {
  if (args.length === 0) {
    return new ScrollableElement("scrollable", {}, [])
  } else if (args.length === 1) {
    if (Array.isArray(args[0]) || typeof args[0] === "function") {
      return new ScrollableElement("scrollable", {}, args[0])
    } else {
      return new ScrollableElement("scrollable", args[0], [])
    }
  } else {
    return new ScrollableElement("scrollable", args[0], args[1])
  }
}
