import { type APP_COMMAND_TYPES } from '../protocol/Constants'
import { BleProtocolService } from './BleProtocolService'

export class FileTransferService {
  private static instance: FileTransferService
  private protocol = BleProtocolService.getInstance()

  private constructor() {}

  public static getInstance(): FileTransferService {
    if (!FileTransferService.instance) {
      FileTransferService.instance = new FileTransferService()
    }
    return FileTransferService.instance
  }

  public async transferFile(
    deviceId: string,
    file: string | ArrayBuffer,
    type: APP_COMMAND_TYPES,
    onProgress?: (progress: number) => void,
  ): Promise<void> {
    try {
      const startAt = Date.now()
      let arrayBuffer: ArrayBuffer
      if (file instanceof ArrayBuffer) {
        arrayBuffer = file
      } else {
        const response = await fetch(file)
        if (!response.ok) {
          throw new Error(`Failed to load file: ${response.statusText}`)
        }
        const blob = await response.blob()
        const reader = new FileReader()
        arrayBuffer = await new Promise<ArrayBuffer>((resolve, reject) => {
          reader.onload = () => resolve(reader.result as ArrayBuffer)
          reader.onerror = reject
          reader.readAsArrayBuffer(blob)
        })
      }
      await this.protocol.send(deviceId, type, arrayBuffer, onProgress)
      const transferredAt = Date.now()
      console.debug(`File transferred in ${(transferredAt - startAt) / 1000} s`)
    } catch (e) {
      console.error('File transfer failed', e)
      throw e
    }
  }
}
