'use client'

import { omit } from 'ramda'
import { useEffect, useRef, useState } from 'react'
import { Scorm12API, Scorm2004API } from 'scorm-again'

export type ScormVersion = '1.2' | '2004'

export type ScormPlayerProps = {
  settings: Record<string, any>
  scormVersion: ScormVersion
  scormState: Record<string, any>
  scormContentPath: string
  className?: string
  onCommit?: (value: any) => void
  setValue?: (element: string, value: any) => void
}

// https://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference
export function ScormPlayer({
  settings,
  scormVersion,
  scormState,
  scormContentPath,
  className,
  onCommit
}: ScormPlayerProps) {
  const [iframeLoaded, setIframeLoaded] = useState(false)
  const scormApiRef = useRef<Scorm12API | Scorm2004API | null>(null)

  useEffect(() => {
    const cls = scormVersion === '1.2' ? Scorm12API : Scorm2004API
    const scormApi = new cls(settings)
    scormApi.loadFromJSON(omit(['interactions'], scormState))
    // scormApi.loadFromFlattenedJSON(scormState)
    scormApiRef.current = scormApi

    if (scormApi instanceof Scorm12API) {
      window.API = scormApi

      scormApi.on('LMSCommit', function () {
        onCommit?.(scormApi.renderCommitCMI(true))
      })
    }

    if (scormApi instanceof Scorm2004API) {
      window.API_1484_11 = scormApi

      scormApi.on('Commit', function () {
        onCommit?.(scormApi.renderCommitCMI(true))
      })
    }

    setIframeLoaded(true)

    return () => {
      scormApiRef.current = null
    }
  }, [])

  useEffect(() => {
    if (!scormApiRef.current) {
      return
    }

    const scormApi = scormApiRef.current
    let unloaded = false

    function unload() {
      if (unloaded || scormApi.isTerminated()) {
        return false
      }

      if (scormApi instanceof Scorm12API) {
        scormApi.LMSSetValue('cmi.core.exit', 'suspend')
        scormApi.LMSCommit()
        scormApi.LMSFinish()
      }

      if (scormApi instanceof Scorm2004API) {
        scormApi.SetValue('cmi.exit', 'suspend')
        scormApi.Commit()
        scormApi.Terminate()
      }

      unloaded = true
    }

    window.addEventListener('beforeunload', unload)
    window.addEventListener('pagehide', unload)

    return () => {
      window.removeEventListener('beforeunload', unload)
      window.removeEventListener('pagehide', unload)
    }
  }, [])

  if (iframeLoaded) {
    return <iframe src={`/proxy/${scormContentPath}`} className={className} />
  }
}
