import { UIScreen } from "./UIScreen";

type RouterOptions = {
  showDefaultBackButton?: boolean
}

type Router = {
  get current(): UIScreen<boolean>
  init<T extends boolean>(homePage: UIScreen<T>, opts?: RouterOptions): void
  push<T extends boolean>(screen: UIScreen<T>): void
  replace<T extends boolean>(screen: UIScreen<T>, options?: ReplaceOptions): void
  pop(to?: number): void
  hide(): void
  restore(): void

  addEventListener(channel: "change", callback: (screen: UIScreen<boolean>) => void): void
  removeEventListener(channel: "change", callback: (screen: UIScreen<boolean>) => void): void
}

let currentScreen: UIScreen<any> | null = null
let onChange = <T extends boolean>(screen: UIScreen<T>) => {
  currentScreen = screen;
  for (let callback of (Router as any)._changeListeners) {
    callback(screen)
  }
}

type ReplaceOptions = {
  transition: "slide-from-left" | "slide-from-right" | "slide-from-top" | "slide-from-bottom" | 
    "zoom" | "zoom-out" | "zoom-in" | "fade" | "none"
}

export const Router: Router = /*#__PURE__*/ Object.freeze({

  init(homePage: UIScreen<any>, opts: RouterOptions = {}): void {
    _creatorUI.routerOpen(homePage, onChange, opts.showDefaultBackButton ?? false)
    currentScreen = homePage
  },
  push(screen: UIScreen<any>): void {
    _creatorUI.routerPush(screen)
  },
  replace(screen: UIScreen<any>, opts?: ReplaceOptions): void {
    _creatorUI.routerReplace(screen, opts?.transition ?? "fade")
  },
  pop(to?: number): void {
    _creatorUI.routerPop(to ?? -1)
  },
  hide() {
    _creatorUI.routerHide()
  },
  restore() {
    _creatorUI.routerRestore()
  },

  get current(): UIScreen<any> {
    return currentScreen!
  },
  
  _changeListeners: [] as any[],
  addEventListener(channel: "change", callback: (screen: UIScreen<boolean>) => void): void { 
    if (channel === "change") {
      this._changeListeners.push(callback)
    }
  },
  removeEventListener(channel: "change", callback: (screen: UIScreen<boolean>) => void): void {
    if (channel === "change") {
      let index = this._changeListeners.indexOf(callback)
      if (index >= 0) {
        this._changeListeners.splice(index, 1)
      }
    }
  }
})
