import type { ParallelTaskExecuteContext } from '../handler'
import type { PrivateCustomEventName } from '../types'

import { ParallelHandler } from '../handler'
import { createEventBus } from '../utils'

const $bus = createEventBus<PrivateCustomEventName>()

class DecodeData extends ParallelHandler<Blob, AudioBuffer> {
  private audioContext: AudioContext = new AudioContext()

  public execute(
    context: ParallelTaskExecuteContext<Blob, AudioBuffer>,
  ): void {
    if (context.isLastExecute) {
      this.taskCompletedCallback(context.taskItem.uuid)
      return
    }

    const reader = new FileReader()
    reader.readAsArrayBuffer(new Blob([context.taskItem.original!]))
    reader.onload = (event) => {
      const arrayBuffer = event.target?.result as ArrayBuffer
      if (!arrayBuffer) {
        return
      }

      this.audioContext.decodeAudioData(arrayBuffer, (audioBuffer) => {
        this.forwardToHandler(audioBuffer)
        this.taskCompletedCallback(context.taskItem.uuid)
      })
    }
  }

  protected onFinish(): void {
    if (this.audioContext) {
      this.audioContext.suspend()
      this.audioContext = new AudioContext()
    }
    $bus.emit('_decodeDataFinish')
  }
}

export default DecodeData
