const ComPDFKitViewer = {
  init (options, element) {
    return new Promise((resolve) => {
      element.addEventListener("ready", function ready () {
        element.removeEventListener('ready', ready)
        const iframeWindow = element.querySelector('iframe').contentWindow

        Promise.resolve().then(function() {
          resolve({
            docViewer: iframeWindow.instance,
            Core: iframeWindow.instances.Core,
            UI: iframeWindow.instances.UI
          })
        })

      })
      const viewer = new Viewer(options, element)
    })
  }
}
const docViewer = new Map()
class Viewer {
  static config = {
    path: '',
    webviewerPath: './webviewer/index.html',
  }
  constructor (options, element) {
    if (docViewer.get(element)) return
    this.docId = 0
    docViewer.set(element, true)
    this.instance = null
    this.options = options
    this.initialDoc = options.pdfUrl || null
    this.element = element
    this.options.path = this.options.path || Viewer.config.path
    const length = this.options.path.length - 1
    length > 0 && "/" !== this.options.path[length] && (this.options.path += "/")
    this.options.webviewerPath = this.options.path + Viewer.config.webviewerPath

    element.addEventListener("ready", (function ready() {
      element.removeEventListener("ready", ready)
    }))
    this.create()
  }

  _createEvent (e, t) {
    let n;
    try {
      n = new CustomEvent(e, {
          detail: t,
          bubbles: true,
          cancelable: true
      })
    } catch (o) {
        (n = document.createEvent("Event")).initEvent(e, true, true),
        n.detail = t
    }
    return n
  }

  create() {
    if (this.initialDoc) {
      this.initialDoc = encodeURIComponent(JSON.stringify(this.initialDoc))
      this._create()
    } else {
      this._create()
    }
  }

  _create () {
    this.docId++
    if (!this._trigger) {
      this._trigger = function(e, t) {
        var n = this._createEvent(e, t);
        this.element.dispatchEvent(n)
      }
    }
    this.createViewer()
  }

  createViewer () {
    const self = this
    let webviewerUrl = this.options.webviewerPath
    if (this.initialDoc) {
      webviewerUrl += "#d=".concat(this.initialDoc)
    } else {
      webviewerUrl += '#'
    }
    webviewerUrl += "&docId=".concat(this.docId)
    this.options.showToolbarControl !== undefined && (webviewerUrl += "&header=".concat(this.options.showToolbarControl ? "true": "false"))
    const iframe = document.createElement("iframe")
    iframe.id = "webviewer-" + this.docId
    iframe.src = webviewerUrl
    iframe.frameBorder = 0
    iframe.width = "100%"
    iframe.height = "100%"
    iframe.setAttribute("allowfullscreen", true)
    iframe.setAttribute("webkitallowfullscreen", true)
    iframe.setAttribute("mozallowfullscreen", true)
    this.iframe = iframe
    this.options?.backgroundColor && iframe.setAttribute("data-bgcolor", this.options.backgroundColor),
    this.options?.assetPath && iframe.setAttribute("data-assetpath", encodeURIComponent(this.options.assetPath)),
    this.element.appendChild(iframe)

    this.loadListener = async function() {
      var $iframe = self.iframe;
      self.instance = $iframe.contentWindow.instance;
      await self.instance.initOptions(self.options)
    }
    iframe.addEventListener("load", this.loadListener)

    this.messageHandler = function (event) {
      if ("documentViewerLoaded" === event.data.type && event.data.docId === self.docId) {
        try {
          self.instance = self.iframe.contentWindow.instance
        } catch(e) {} finally {
          window.removeEventListener("message", this.messageHandler),
          self._documentViewerLoaded(self.iframe)
        }
      }
    }
    window.addEventListener("message", this.messageHandler)
  }

  _documentViewerLoaded (iframe) {
    this._trigger("ready")
    if (this.options.pdfUrl) {
      this.iframe.contentWindow.instances.UI.loadDocument(this.options.pdfUrl)
    }
  }
}

export default ComPDFKitViewer
