import { type H5BridgeMessage, type H5ExperienceRequest } from '../../game/experience/h5Experience'

type ExperienceWebViewPageData = {
  pageTitle: string
  pageSubtitle: string
  presentation: 'sheet' | 'dialog' | 'fullscreen'
  webViewSrc: string
  webViewReady: boolean
  loadErrorText: string
  panelBodyHeightPx: number
}

let currentRequest: H5ExperienceRequest | null = null
let currentEventChannel: WechatMiniprogram.EventChannel | null = null
let pageResolved = false

function appendQueryParam(url: string, key: string, value: string): string {
  const separator = url.indexOf('?') >= 0 ? '&' : '?'
  return `${url}${separator}${key}=${encodeURIComponent(value)}`
}

function buildWebViewSrc(request: H5ExperienceRequest): string {
  let nextUrl = request.url
  nextUrl = appendQueryParam(nextUrl, 'cmrBridge', request.bridgeVersion)
  nextUrl = appendQueryParam(nextUrl, 'cmrKind', request.kind)
  return nextUrl
}

function emitFallbackAndClose() {
  if (!currentRequest || !currentEventChannel) {
    return
  }
  if (!pageResolved) {
    pageResolved = true
    currentEventChannel.emit('fallback', currentRequest.fallback)
  }
  wx.navigateBack({
    fail: () => {},
  })
}

function emitCloseAndBack(payload?: Record<string, unknown>) {
  if (currentEventChannel && !pageResolved) {
    pageResolved = true
    currentEventChannel.emit('close', payload || {})
  }
  wx.navigateBack({
    fail: () => {},
  })
}

Page<ExperienceWebViewPageData, WechatMiniprogram.IAnyObject>({
  data: {
    pageTitle: '内容体验',
    pageSubtitle: '',
    presentation: 'sheet',
    webViewSrc: '',
    webViewReady: false,
    loadErrorText: '',
    panelBodyHeightPx: 420,
  },

  onLoad() {
    const systemInfo = wx.getSystemInfoSync()
    const windowHeight = typeof systemInfo.windowHeight === 'number' ? systemInfo.windowHeight : 700
    pageResolved = false
    currentRequest = null
    currentEventChannel = null
    this.setData({
      pageTitle: '内容体验',
      pageSubtitle: '',
      presentation: 'sheet',
      webViewSrc: '',
      webViewReady: false,
      loadErrorText: '',
      panelBodyHeightPx: Math.max(420, Math.floor(windowHeight * 0.62)),
    })

    try {
      currentEventChannel = this.getOpenerEventChannel()
    } catch {
      currentEventChannel = null
    }

    if (!currentEventChannel) {
      return
    }

    currentEventChannel.on('init', (request: H5ExperienceRequest) => {
      currentRequest = request
      const presentation = request.presentation || 'sheet'
      const panelHeightPx = presentation === 'dialog'
        ? Math.max(420, Math.floor(windowHeight * 0.7))
        : presentation === 'fullscreen'
          ? Math.max(520, windowHeight - 24)
          : Math.max(420, Math.floor(windowHeight * 0.72))
      const headerHeightPx = presentation === 'fullscreen' ? 84 : 76
      this.setData({
        pageTitle: request.title || '内容体验',
        pageSubtitle: request.subtitle || '',
        presentation,
        webViewSrc: buildWebViewSrc(request),
        webViewReady: true,
        loadErrorText: '',
        panelBodyHeightPx: Math.max(240, panelHeightPx - headerHeightPx),
      })
    })
  },

  onUnload() {
    if (currentEventChannel && !pageResolved) {
      currentEventChannel.emit('close', {})
    }
    pageResolved = false
    currentRequest = null
    currentEventChannel = null
  },

  handleWebViewMessage(event: WechatMiniprogram.CustomEvent) {
    const dataList = event.detail && Array.isArray(event.detail.data)
      ? event.detail.data
      : []
    const rawMessage = dataList.length ? dataList[dataList.length - 1] : null
    if (!rawMessage || typeof rawMessage !== 'object') {
      return
    }

    const message = rawMessage as H5BridgeMessage
    const action = message.action || message.type || ''
    if (!action) {
      return
    }

    if (action === 'close') {
      emitCloseAndBack(message.payload)
      return
    }

    if (action === 'submitResult') {
      if (currentEventChannel) {
        currentEventChannel.emit('submitResult', message.payload || {})
      }
      return
    }

    if (action === 'fallback') {
      emitFallbackAndClose()
    }
  },

  handleWebViewError() {
    this.setData({
      loadErrorText: '页面打开失败，已回退原生内容',
    })
    emitFallbackAndClose()
  },

  handleCloseTap() {
    emitCloseAndBack({})
  },
})
