<template>
  <div class="wx-scan-page">
    <div class="scan-container">
      <!-- 加载状态 -->
      <div v-if="status === 'loading'" class="status-box">
        <a-spin size="large" />
        <p class="status-text">{{ loadingText }}</p>
      </div>

      <!-- 扫码成功 -->
      <div v-else-if="status === 'success'" class="status-box success">
        <CheckCircleOutlined class="status-icon success-icon" />
        <h2 class="status-title">登录成功</h2>
        <p class="status-text">正在跳转...</p>
        <div class="user-info" v-if="userInfo">
          <a-avatar :size="64" :src="userInfo.avatar">
            <template v-if="!userInfo.avatar"><UserOutlined /></template>
          </a-avatar>
          <p class="username">{{ userInfo.nickname || userInfo.username }}</p>
        </div>
      </div>

      <!-- 需要绑定 -->
      <div v-else-if="status === 'bind_required'" class="status-box warning">
        <ExclamationCircleOutlined class="status-icon warning-icon" />
        <h2 class="status-title">需要绑定手机号</h2>
        <p class="status-text">{{ message_text }}</p>
        <a-button type="primary" size="large" @click="goToBindPhone">去绑定手机号</a-button>
      </div>

      <!-- 扫码失败 -->
      <div v-else-if="status === 'error'" class="status-box error">
        <CloseCircleOutlined class="status-icon error-icon" />
        <h2 class="status-title">扫码失败</h2>
        <p class="status-text">{{ message_text }}</p>
        <a-button type="primary" size="large" @click="retry">重新扫码</a-button>
      </div>

      <!-- 未找到用户 -->
      <div v-else-if="status === 'not_bound'" class="status-box warning">
        <ExclamationCircleOutlined class="status-icon warning-icon" />
        <h2 class="status-title">账号未绑定</h2>
        <p class="status-text">{{ message_text }}</p>
        <div class="action-buttons">
          <a-button type="primary" size="large" @click="goToRegister">前往注册</a-button>
          <a-button size="large" @click="retry">重新扫码</a-button>
        </div>
      </div>


      <!-- 底部安全提示 -->
      <div class="security-tip">
        <SafetyCertificateOutlined />
        <span>请确认是您本人操作，如非本人操作请忽略</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { message } from 'ant-design-vue'
import {
  CheckCircleOutlined,
  CloseCircleOutlined,
  ExclamationCircleOutlined,
  SafetyCertificateOutlined,
  UserOutlined
} from '@ant-design/icons-vue'
import {
  checkQrCodeStatus,
  getWechatOAuthUrl,
  wechatScanConfirm,
  type WechatScanResponse
} from '@/api/passport/qrLogin'
import { setToken } from '@/utils/token-util'

definePageMeta({ layout: 'blank' })

const route = useRoute()
const router = useRouter()

const status = ref<'loading' | 'success' | 'error' | 'bind_required' | 'not_bound' | 'not_wechat'>('loading')
const message_text = ref('')
const loadingText = ref('正在等待扫码...')
const userInfo = ref<any>(null)

const token = computed(() => String(route.query.token || ''))
const code = computed(() => String(route.query.code || ''))

let pollTimer: ReturnType<typeof setInterval> | null = null

const isWechatBrowser = computed(() => {
  if (!import.meta.client) return false
  return /MicroMessenger/i.test(window.navigator.userAgent)
})

async function redirectToWechatOAuth() {
  if (!import.meta.client || !token.value) return

  try {
    loadingText.value = '正在拉起微信授权...'
    const oauthUrl = await getWechatOAuthUrl(token.value)
    if (!oauthUrl) {
      throw new Error('未获取到微信授权地址')
    }
    window.location.replace(oauthUrl)
  } catch (error: unknown) {
    console.error('获取微信授权地址失败:', error)
    status.value = 'error'
    message_text.value = error instanceof Error ? error.message : '获取微信授权地址失败，请重试'
  }
}

/**
 * 轮询检查登录状态（扫码关注登录模式）
 */
async function redirectToBindPhone(tip?: string) {
  status.value = 'bind_required'
  message_text.value = tip || '请先绑定手机号完成登录'
  message.info(message_text.value)
  await router.replace(`/bind-phone?token=${token.value}`)
}

async function pollLoginStatus() {
  if (!token.value) return

  try {
    const response = await checkQrCodeStatus(token.value)

    if (response.status === 'confirmed') {
      // 登录成功
      stopPolling()
      handleLoginSuccess({
        status: 'success',
        accessToken: response.accessToken || response.access_token,
        userInfo: response.userInfo,
        tenantId: response.tenantId ? Number(response.tenantId) : undefined
      })
    } else if (response.status === 'bind_phone') {
      stopPolling()
      await redirectToBindPhone(response.message)
    } else if (response.status === 'expired') {
      // 二维码过期
      stopPolling()
      status.value = 'error'
      message_text.value = '二维码已过期，请刷新后重新扫码'
    } else if (response.status === 'scanned') {
      // 已扫码，等待公众号事件回写
      loadingText.value = '已识别扫码，请关注公众号后自动登录'
    } else {
      // pending 状态，继续等待
      loadingText.value = '等待扫码...'
    }
  } catch (error) {
    console.warn('检查登录状态失败:', error)
    // 轮询错误不影响，继续轮询
  }
}

function stopPolling() {
  if (pollTimer) {
    clearInterval(pollTimer)
    pollTimer = null
  }
}

onUnmounted(() => {
  stopPolling()
})

onMounted(async () => {
  // 如果没有 token，显示错误
  if (!token.value) {
    status.value = 'error'
    message_text.value = '二维码参数错误'
    return
  }

  // 如果有 code（微信授权回调），直接用 code 登录
  if (code.value) {
    await handleLoginWithCode()
    return
  }

  // 微信内打开扫码页时，先拉起 OAuth 获取身份，再由回调继续登录
  if (isWechatBrowser.value) {
    await redirectToWechatOAuth()
    return
  }

  // 非微信环境下保留轮询兜底，兼容服务端推送扫码状态的场景
  status.value = 'loading'
  loadingText.value = '等待扫码，请在微信中扫描二维码...'

  // 立即检查一次
  await pollLoginStatus()
  // 每2秒轮询一次
  pollTimer = setInterval(pollLoginStatus, 2000)
})

async function handleLoginWithCode() {
  status.value = 'loading'
  loadingText.value = '正在验证身份...'
  try {
    const response: WechatScanResponse = await wechatScanConfirm({
      token: token.value,
      code: code.value
    })

    if ((response.status === 'success' || response.status === 'confirmed') && (response.accessToken || response.access_token)) {
      handleLoginSuccess({
        ...response,
        accessToken: response.accessToken || response.access_token
      })
    } else if (response.status === 'bind_required' || response.status === 'bind_phone') {
      await redirectToBindPhone(response.message)
    } else {
      status.value = 'not_bound'
      message_text.value = response.message || '该微信未绑定平台账号'
    }
  } catch (error: unknown) {
    console.error('微信扫码登录失败:', error)
    status.value = 'error'
    message_text.value = error instanceof Error ? error.message : '登录失败，请重试'
  }
}

function handleLoginSuccess(response: WechatScanResponse) {
  status.value = 'success'
  userInfo.value = response.userInfo

  // 保存 token
  if (response.accessToken) {
    setToken(response.accessToken, true)
    if (response.tenantId) {
      localStorage.setItem('TenantId', String(response.tenantId))
    }
    if (userInfo.value?.userId) {
      localStorage.setItem('UserId', String(userInfo.value.userId))
    }
  }

  message.success('登录成功')

  // 2秒后跳转到首页
  setTimeout(() => {
    router.push('/')
  }, 2000)
}

function goToBindPhone() {
  router.push(`/bind-phone?token=${token.value}`)
}

function goToRegister() {
  router.push('/register')
}

function retry() {
  router.replace('/login')
}
</script>

<style scoped>
.wx-scan-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.scan-container {
  width: 420px;
  max-width: 100%;
  background: #fff;
  border-radius: 16px;
  padding: 40px 32px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2);
  text-align: center;
}

.status-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  min-height: 280px;
  justify-content: center;
}

.status-icon {
  font-size: 72px;
}

.success-icon {
  color: #52c41a;
}

.warning-icon {
  color: #faad14;
}

.error-icon {
  color: #ff4d4f;
}

.status-title {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: #262626;
}

.status-text {
  margin: 0;
  font-size: 14px;
  color: #8c8c8c;
  line-height: 1.6;
}

.user-info {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}

.username {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  color: #262626;
}

.action-buttons {
  display: flex;
  gap: 12px;
  margin-top: 8px;
}

.security-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid #f0f0f0;
  color: #8c8c8c;
  font-size: 12px;
}

.security-tip :deep(.anticon) {
  color: #52c41a;
}
</style>
