import { computed, onBeforeUnmount, ref, watch } from 'vue' import { showError, showSuccess } from '@/lib/feedback' import { createTencentBrowserSession, refreshTencentBrowserSessionPage, removeTencentBrowserSession, } from '@/services/tencent/session' import { redeemTencentBrowserSession } from '@/services/tencent/redeem' import type { TencentBrowserSessionData, TencentLoginType } from '@/types/tencent/session' import { notifyTencentActionError } from './tencent/session-errors' import { useTencentBrowserSessionPolling } from './tencent/useTencentBrowserSessionPolling' import { useTencentBrowserSessionPresentation } from './tencent/useTencentBrowserSessionPresentation' const DEFAULT_LOGIN_TYPE: TencentLoginType = 'qq' export function useTencentBrowserSessionPage() { const sessionLoading = ref(false) const redeemLoading = ref(false) const loginType = ref(DEFAULT_LOGIN_TYPE) const session = ref(null) const redeemCode = ref('') const maxAttempts = ref(6) const roleConfirmed = ref(false) const activityInfo = computed(() => session.value?.activityInfo || null) const roleReady = computed(() => Boolean(activityInfo.value?.role?.ready)) const hasSession = computed(() => Boolean(session.value?.sessionId)) const loginTypeLabel = computed(() => (loginType.value === 'wx' ? '微信' : 'QQ')) const loginTabs = [ { value: 'qq' as const, label: 'QQ账号登录' }, { value: 'wx' as const, label: '微信账号登录' }, ] const { refreshSession, resetPolling, resetPollingWarning, restartPollingIfActive, sessionNotice, startPolling, } = useTencentBrowserSessionPolling({ session, sessionLoading, notifyActionError: notifyTencentActionError, }) const { canRedeem, initButtonLabel, qrImage, redeemBlockedReason, redeemButtonLabel, resultFacts, roleFacts, scanInstruction, screenshotEmptyMessage, screenshotEmptyTitle, screenshotUrl, statusLabel, } = useTencentBrowserSessionPresentation({ activityInfo, hasSession, loginTypeLabel, redeemLoading, roleConfirmed, roleReady, session, sessionLoading, sessionNotice, }) watch( () => [ session.value?.sessionId || '', activityInfo.value?.nickname || '', activityInfo.value?.role?.roleId || '', activityInfo.value?.role?.roleName || '', activityInfo.value?.role?.area || '', activityInfo.value?.role?.partition || '', ].join('|'), () => { roleConfirmed.value = false }, ) async function createSessionFlow(nextLoginType = loginType.value) { resetPolling() resetPollingWarning() sessionLoading.value = true try { loginType.value = nextLoginType await teardownSession() const response = await createTencentBrowserSession({ loginType: nextLoginType, }) if (response.code !== 0) { throw new Error(response.msg || '创建浏览器会话失败') } session.value = response.data startPolling() } catch (error) { notifyTencentActionError(error, '创建浏览器会话失败') } finally { sessionLoading.value = false } } async function reloadSessionPage() { if (!session.value?.sessionId) { return } resetPolling() resetPollingWarning() sessionLoading.value = true try { const response = await refreshTencentBrowserSessionPage(session.value.sessionId) if (response.code !== 0) { throw new Error(response.msg || '刷新后端页面失败') } session.value = response.data restartPollingIfActive(response.data) } catch (error) { notifyTencentActionError(error, '刷新后端页面失败') await refreshSession({ silent: true }) restartPollingIfActive() } finally { sessionLoading.value = false } } async function switchLoginType(nextLoginType: TencentLoginType) { if (nextLoginType === loginType.value) { return } loginType.value = nextLoginType if (session.value?.sessionId) { await createSessionFlow(nextLoginType) } } async function redeemNow() { if (!session.value?.sessionId) { showError('请先创建浏览器会话') return } if (!redeemCode.value.trim()) { showError('请输入兑换码') return } redeemLoading.value = true resetPolling() resetPollingWarning() try { const response = await redeemTencentBrowserSession(session.value.sessionId, { code: redeemCode.value.trim(), maxAttempts: maxAttempts.value, }) if (response.code !== 0) { throw new Error(response.msg || '浏览器兑换失败') } session.value = response.data showSuccess(response.msg || '兑换完成') } catch (error) { notifyTencentActionError(error, '浏览器兑换失败') await refreshSession({ silent: true }) } finally { redeemLoading.value = false } } async function teardownSession() { if (!session.value?.sessionId) { return } const sessionId = session.value.sessionId session.value = null try { await removeTencentBrowserSession(sessionId) } catch { // ignore close failures on local teardown } } onBeforeUnmount(() => { resetPolling() void teardownSession() }) return { activityInfo, canRedeem, teardownSession, createSessionFlow, hasSession, initButtonLabel, loginTabs, loginType, loginTypeLabel, maxAttempts, qrImage, redeemBlockedReason, redeemButtonLabel, redeemCode, redeemLoading, redeemNow, reloadSessionPage, resultFacts, roleConfirmed, roleFacts, scanInstruction, screenshotEmptyMessage, screenshotEmptyTitle, screenshotUrl, session, sessionLoading, sessionNotice, statusLabel, switchLoginType, } }