import { clearBackendAuthTokens, loadBackendAuthTokens, loadBackendBaseUrl } from '../../utils/backendAuth'
import { finishSession, getEntryHome, type BackendCardResult, type BackendEntryHomeResult } from '../../utils/backendApi'
import { reportBackendClientLog } from '../../utils/backendClientLogs'
import { setGlobalMockDebugBridgeEnabled } from '../../utils/globalMockDebugBridge'
import { clearSessionRecoverySnapshot, loadSessionRecoverySnapshot } from '../../game/core/sessionRecovery'
import { getBackendSessionContextFromLaunchEnvelope, prepareMapPageUrlForRecovery } from '../../utils/gameLaunch'

const DEFAULT_CHANNEL_CODE = 'mini-demo'
const DEFAULT_CHANNEL_TYPE = 'wechat_mini'

type HomePageData = {
  loading: boolean
  statusText: string
  userNameText: string
  tenantText: string
  channelText: string
  ongoingSessionText: string
  recentSessionText: string
  ongoingRuntimeText: string
  recentRuntimeText: string
  ongoingActionHintText: string
  showOngoingPanel: boolean
  canRecoverOngoing: boolean
  canAbandonOngoing: boolean
  cards: BackendCardResult[]
}

function formatSessionSummary(session?: BackendEntryHomeResult['ongoingSession'] | null): string {
  if (!session) {
    return '无'
  }

  const title = session.eventName || session.eventDisplayName || session.eventId || session.id || session.sessionId
  const status = session.status || session.sessionStatus || '--'
  const route = session.routeCode || session.variantName || '默认赛道'
  return `${title} / ${status} / ${route}`
}

function formatRuntimeSummary(session?: BackendEntryHomeResult['ongoingSession'] | null): string {
  if (!session || !session.runtime) {
    return '运行对象 --'
  }

  const runtime = session.runtime
  const placeText = runtime.placeName || runtime.placeId || '--'
  const mapText = runtime.mapName || runtime.mapId || '--'
  const variantText = runtime.courseVariantId || session.variantName || session.variantId || '--'
  return `地点 ${placeText} / 地图 ${mapText} / 赛道 ${variantText}`
}

function requireAuthToken(): string | null {
  const app = getApp<IAppOption>()
  const tokens = app.globalData && app.globalData.backendAuthTokens
    ? app.globalData.backendAuthTokens
    : loadBackendAuthTokens()
  return tokens && tokens.accessToken ? tokens.accessToken : null
}

function getRecoverySnapshotSessionId(): string {
  const snapshot = loadSessionRecoverySnapshot()
  if (!snapshot) {
    return ''
  }
  const context = getBackendSessionContextFromLaunchEnvelope(snapshot.launchEnvelope)
  return context && context.sessionId ? context.sessionId : ''
}

Page({
  data: {
    loading: false,
    statusText: '准备加载首页',
    userNameText: '--',
    tenantText: '--',
    channelText: '--',
    ongoingSessionText: '无',
    recentSessionText: '无',
    ongoingRuntimeText: '运行对象 --',
    recentRuntimeText: '运行对象 --',
    ongoingActionHintText: '当前没有可恢复的进行中对局',
    showOngoingPanel: false,
    canRecoverOngoing: false,
    canAbandonOngoing: false,
    cards: [],
  } as HomePageData,

  onLoad() {
    this.loadEntryHome()
  },

  onShow() {
    this.loadEntryHome()
  },

  async loadEntryHome() {
    const accessToken = requireAuthToken()
    if (!accessToken) {
      wx.redirectTo({ url: '/pages/login/login' })
      return
    }

    this.setData({
      loading: true,
      statusText: '正在加载首页聚合',
    })

    try {
      const result = await getEntryHome({
        baseUrl: loadBackendBaseUrl(),
        accessToken,
        channelCode: DEFAULT_CHANNEL_CODE,
        channelType: DEFAULT_CHANNEL_TYPE,
      })
      this.applyEntryHomeResult(result)
    } catch (error) {
      const message = error && (error as { message?: string }).message ? (error as { message: string }).message : '未知错误'
      this.setData({
        loading: false,
        statusText: `首页加载失败：${message}`,
      })
    }
  },

  applyEntryHomeResult(result: BackendEntryHomeResult) {
    const ongoingSession = result.ongoingSession || null
    const recoverySnapshotSessionId = getRecoverySnapshotSessionId()
    const canRecoverOngoing = !!ongoingSession && !!recoverySnapshotSessionId
      && ongoingSession.id === recoverySnapshotSessionId
    const canAbandonOngoing = canRecoverOngoing
    const ongoingActionHintText = !ongoingSession
      ? '当前没有可恢复的进行中对局'
      : canRecoverOngoing
        ? '检测到本机仍保留这局的恢复记录，你可以继续恢复或主动放弃。'
        : '检测到后端存在进行中对局，但本机当前没有匹配的恢复快照。'
    reportBackendClientLog({
      level: 'info',
      category: 'entry-home',
      message: 'entry home loaded',
      details: {
        ongoingSessionId: result.ongoingSession && result.ongoingSession.id ? result.ongoingSession.id : '',
        ongoingEventId: result.ongoingSession && result.ongoingSession.eventId ? result.ongoingSession.eventId : '',
        recentSessionId: result.recentSession && result.recentSession.id ? result.recentSession.id : '',
        recentEventId: result.recentSession && result.recentSession.eventId ? result.recentSession.eventId : '',
        cardEventIds: (result.cards || []).map((item) => (item.event && item.event.id ? item.event.id : '')),
        hasOngoingSession: !!ongoingSession,
        recoverySnapshotSessionId,
        canRecoverOngoing,
      },
    })
    this.setData({
      loading: false,
      statusText: '首页加载完成',
      userNameText: result.user.nickname || result.user.publicId || result.user.id,
      tenantText: `${result.tenant.name} (${result.tenant.code})`,
      channelText: `${result.channel.displayName} / ${result.channel.code}`,
      ongoingSessionText: formatSessionSummary(result.ongoingSession),
      recentSessionText: formatSessionSummary(result.recentSession),
      ongoingRuntimeText: formatRuntimeSummary(result.ongoingSession),
      recentRuntimeText: formatRuntimeSummary(result.recentSession),
      ongoingActionHintText,
      showOngoingPanel: !!ongoingSession,
      canRecoverOngoing,
      canAbandonOngoing,
      cards: result.cards || [],
    })
  },

  handleRefresh() {
    this.loadEntryHome()
  },

  handleOpenCard(event: WechatMiniprogram.TouchEvent) {
    const eventId = event.currentTarget.dataset.eventId as string | undefined
    if (!eventId) {
      wx.showToast({
        title: '该卡片暂无活动入口',
        icon: 'none',
      })
      return
    }

    wx.navigateTo({
      url: `/pages/event/event?eventId=${encodeURIComponent(eventId)}`,
    })
  },

  handleOpenRecentResult() {
    wx.navigateTo({
      url: '/pages/results/results',
    })
  },

  handleOpenEventList() {
    wx.navigateTo({
      url: '/pages/events/events',
    })
  },

  handleOpenExperienceMaps() {
    wx.navigateTo({
      url: '/pages/experience-maps/experience-maps',
    })
  },

  handleResumeOngoing() {
    const snapshot = loadSessionRecoverySnapshot()
    if (!snapshot) {
      wx.showToast({
        title: '本机未找到恢复快照',
        icon: 'none',
      })
      this.loadEntryHome()
      return
    }

    wx.navigateTo({
      url: prepareMapPageUrlForRecovery(snapshot.launchEnvelope),
    })
  },

  handleAbandonOngoing() {
    const snapshot = loadSessionRecoverySnapshot()
    if (!snapshot) {
      wx.showToast({
        title: '本机未找到恢复快照',
        icon: 'none',
      })
      this.loadEntryHome()
      return
    }

    const sessionContext = getBackendSessionContextFromLaunchEnvelope(snapshot.launchEnvelope)
    if (!sessionContext) {
      clearSessionRecoverySnapshot()
      wx.showToast({
        title: '已清理本机恢复记录',
        icon: 'none',
      })
      this.loadEntryHome()
      return
    }

    wx.showModal({
      title: '放弃进行中的游戏',
      content: '放弃后，这局游戏会记为已取消，且不会再出现在“进行中”。',
      confirmText: '确认放弃',
      cancelText: '先保留',
      success: (result) => {
        if (!result.confirm) {
          return
        }

        finishSession({
          baseUrl: loadBackendBaseUrl(),
          sessionId: sessionContext.sessionId,
          sessionToken: sessionContext.sessionToken,
          status: 'cancelled',
          summary: {},
        }).catch(() => {
          wx.showToast({
            title: '取消上报失败，请稍后重试',
            icon: 'none',
          })
        }).finally(() => {
          clearSessionRecoverySnapshot()
          this.loadEntryHome()
        })
      },
    })
  },

  handleLogout() {
    clearBackendAuthTokens()
    setGlobalMockDebugBridgeEnabled(false)
    const app = getApp<IAppOption>()
    if (app.globalData) {
      app.globalData.backendAuthTokens = null
    }
    wx.redirectTo({
      url: '/pages/login/login',
    })
  },
})
