import { browser, getRandomKey } from '/src/helpers/utils'

export type EnumApiType =
  | 'cloudDetail'
  | 'cloudDestroy'
  | 'cloudVolume'
  | 'cloudMetronome'
  | 'cloudGetMediaStatus'
  | 'cloudPlay'
  | 'cloudSuspend'
  | 'cloudTimeUpdae'
  | 'cloudplayed'
  | 'cloudSetCurrentTime'
  | 'cloudChangeSpeed'
  | 'savePicture'
  | 'openWebView'
  | 'openCamera'
  | 'closeCamera'
  | 'back'
  | 'openAccompanyWebView'
  | 'startCapture'
  | 'endCapture'
  | 'setCaptureMode'
  | 'proxyServiceMessage'
  | 'startEvaluating'
  | 'endEvaluating'
  | 'videoUpdate'
  | 'shareAchievements'
  | 'resumeRecording'
  | 'startRecording'
  | 'stopRecording'

export interface IPostMessage {
  api: string | EnumApiType
  content?: any
}

/**
 * 劫持postMessage
 */

// const originalPostMessage = window.postMessage

// window.postMessage = (message: IPostMessage) => {
//   // console.log('通过劫持', message)
//   originalPostMessage(message, '*')
// }

/**
 *
 * 目前已支持API
 *
 * openWebView
 *
 */

export type CallBack = (evt?: IPostMessage) => void

// eslint-disable-next-line @typescript-eslint/no-empty-function
const loop = () => {}

const calls: { [key: string]: CallBack | CallBack[] } = {}

const browserInfo = browser()

if (browserInfo.isApp) {
  window.addEventListener('message', (evt) => {
    // console.log('app回调', evt?.data)
    try {
      const data = evt.data ? (typeof evt.data === 'object' ? evt.data : JSON.parse(evt.data)) : {}
      const uuid = data.content?.uuid || data.uuid
      try {
        if (data.content) {
          data.content = typeof data.content === 'object' ? data.content : JSON.parse(data.content)
        }
      } catch (error) {}

      if (!uuid) {
        const keys = Object.keys(calls).filter((key) => key.indexOf(data.api) === 0)
        for (const key of keys) {
          const callback = calls[key] || loop
          typeof callback === 'function' && callback(data)
          if (Array.isArray(callback)) {
            callback.forEach((cb) => {
              typeof cb === 'function' && cb(data)
            })
          }
        }
        return
      }
      const callid = data.content?.uuid || data.uuid || data.api + data.uuid
      const callback = calls[callid] || loop
      typeof callback === 'function' && callback(data)
    } catch (error) {
      console.error('通信消息解析错误', error)
    }
  })
}

const instance: any = (window as any).ORCHESTRA || (window as any).webkit?.messageHandlers?.ORCHESTRA

export const postMessage = (data: IPostMessage, callback?: CallBack) => {
  if (browserInfo.isApp) {
    const uuid = getRandomKey()
    calls[uuid] = callback || loop
    data.content = data.content ? { ...data.content, uuid } : { uuid }
    console.log('h5发送:', JSON.stringify(data))
    instance.postMessage(JSON.stringify(data))
  }
}

export const listenerMessage = (api: string, callback: CallBack) => {
  if (browserInfo.isApp) {
    const uuid = api
    if (!calls[uuid]) {
      calls[uuid] = []
    }
    ;(calls[uuid] as CallBack[]).push(callback || loop)
  }
}

export const removeListenerMessage = (api: string, callback: CallBack) => {
  if (browserInfo.isApp) {
    const uuid = api
    if (Array.isArray(calls[uuid])) {
      const indexOf = (calls[uuid] as CallBack[]).indexOf(callback)
      ;(calls[uuid] as CallBack[]).splice(indexOf, 1)
    }
  }
}

export const promisefiyPostMessage = (data: IPostMessage): Promise<IPostMessage | undefined> => {
  return new Promise((resolve) => {
    postMessage(data, (res) => resolve(res))
  })
}
