import { createVNode, render } from 'vue'
import type { App, VNode } from 'vue'

export type MountContext<P = any> = {
  props?: P
  children?: unknown
  element?: HTMLElement
  app?: App
}
export function mount<P>(
  component: ComponentConstructor<P>,
  { props, children, element, app }: MountContext<P> = {}
) {
  let el = element
  let vNode: VNode | undefined = createVNode(component, props as any, children)

  if (app && app._context) vNode.appContext = app._context
  if (el) {
    render(vNode, el)
    console.log('render', el)
  } else if (typeof document !== 'undefined') {
    render(vNode, (el = document.createElement('div')))
  }

  const destroy = () => {
    if (el) render(null, el)
    el = undefined
    vNode = undefined
  }

  return { vNode, destroy, el }
}

export const genMount =
  (app: App) =>
  <P>(component: ComponentConstructor<P>, context: MountContext<P>) =>
    mount(component, { ...context, app })
