<template>
  <div class="bind-phone-page">
    <div class="bind-card">
      <div class="bind-header">
        <h1>绑定手机号</h1>
        <p>首次通过公众号登录，请先完成手机号绑定</p>
      </div>

      <div v-if="pageState === 'loading'" class="bind-state">
        <a-spin size="large" />
        <span>正在校验登录状态...</span>
      </div>

      <div v-else-if="pageState === 'error'" class="bind-state error">
        <CloseCircleOutlined class="state-icon" />
        <p>{{ pageMessage }}</p>
        <a-button type="primary" @click="goToLogin">返回登录</a-button>
      </div>

      <div v-else class="bind-form-wrap">
        <a-alert
          type="warning"
          show-icon
          :message="pageMessage || '绑定成功后将自动完成当前扫码登录'"
          class="bind-alert"
        />

        <a-form ref="formRef" :model="form" :rules="rules" layout="vertical">
          <a-form-item label="手机号" name="phone">
            <a-input v-model:value="form.phone" size="large" placeholder="请输入手机号" />
          </a-form-item>

          <a-form-item label="短信验证码" name="smsCode">
            <div class="sms-row">
              <a-input v-model:value="form.smsCode" size="large" placeholder="请输入短信验证码" />
              <a-button :disabled="countdown > 0" :loading="sendingSms" size="large" @click="sendSmsCode">
                {{ countdown > 0 ? `${countdown}s 后重试` : '发送验证码' }}
              </a-button>
            </div>
          </a-form-item>

          <a-button type="primary" block size="large" :loading="submitting" @click="submit">
            绑定手机号并登录
          </a-button>
        </a-form>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'
import { message, type FormInstance } from 'ant-design-vue'
import { CloseCircleOutlined } from '@ant-design/icons-vue'
import { checkQrCodeStatus, bindQrLoginPhone, type QrCodeStatusResponse } from '@/api/passport/qrLogin'
import { sendSmsCaptcha } from '@/api/passport/login'
import { setToken } from '@/utils/token-util'

definePageMeta({ layout: 'blank' })

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

const token = computed(() => String(route.query.token || ''))
const formRef = ref<FormInstance>()
const submitting = ref(false)
const sendingSms = ref(false)
const countdown = ref(0)
const pageState = ref<'loading' | 'ready' | 'error'>('loading')
const pageMessage = ref('')
let countdownTimer: ReturnType<typeof setInterval> | null = null

const form = reactive({
  phone: '',
  smsCode: ''
})

const phoneReg = /^1[3-9]\d{9}$/
const rules = reactive({
  phone: [
    { required: true, message: '请输入手机号', type: 'string' },
    { pattern: phoneReg, message: '手机号格式不正确', trigger: 'blur' }
  ],
  smsCode: [{ required: true, message: '请输入短信验证码', type: 'string' }]
})

function stopCountdown() {
  if (countdownTimer) {
    clearInterval(countdownTimer)
    countdownTimer = null
  }
  countdown.value = 0
}

function persistUserInfo(result: QrCodeStatusResponse) {
  const accessToken = result.accessToken || result.access_token
  if (accessToken) {
    setToken(String(accessToken), true)
  }
  if (import.meta.client) {
    if (result.tenantId) {
      localStorage.setItem('TenantId', String(result.tenantId))
    }
    const userId = result.userInfo?.userId
    if (userId) {
      localStorage.setItem('UserId', String(userId))
    }
  }
}

async function applyLoginResult(result: QrCodeStatusResponse, successText = '登录成功') {
  persistUserInfo(result)
  message.success(successText)
  await router.replace('/')
}

async function loadStatus() {
  if (!token.value) {
    pageState.value = 'error'
    pageMessage.value = '缺少二维码参数，请重新扫码'
    return
  }

  try {
    const result = await checkQrCodeStatus(token.value)
    if (result.status === 'confirmed') {
      await applyLoginResult(result)
      return
    }
    if (result.status === 'bind_phone') {
      pageState.value = 'ready'
      pageMessage.value = result.message || '请输入手机号和短信验证码，完成首次登录'
      return
    }
    if (result.status === 'expired') {
      pageState.value = 'error'
      pageMessage.value = '二维码已过期，请返回登录页重新扫码'
      return
    }
    pageState.value = 'error'
    pageMessage.value = '当前二维码尚未进入绑定流程，请先完成扫码关注'
  } catch (error: unknown) {
    pageState.value = 'error'
    pageMessage.value = error instanceof Error ? error.message : '校验扫码状态失败'
  }
}

async function sendSmsCode() {
  if (!phoneReg.test(form.phone)) {
    return message.warning('请先输入正确的手机号')
  }
  sendingSms.value = true
  try {
    await sendSmsCaptcha({ phone: form.phone })
    message.success('验证码已发送')
    stopCountdown()
    countdown.value = 60
    countdownTimer = setInterval(() => {
      countdown.value -= 1
      if (countdown.value <= 0) {
        stopCountdown()
      }
    }, 1000)
  } catch (error: unknown) {
    message.error(error instanceof Error ? error.message : '发送验证码失败')
  } finally {
    sendingSms.value = false
  }
}

async function submit() {
  if (!formRef.value || !token.value) return
  submitting.value = true
  try {
    await formRef.value.validate()
    const result = await bindQrLoginPhone({
      token: token.value,
      phone: form.phone,
      code: form.smsCode
    })
    await applyLoginResult(result, '手机号绑定成功，已完成登录')
  } catch (error: unknown) {
    message.error(error instanceof Error ? error.message : '绑定手机号失败')
  } finally {
    submitting.value = false
  }
}

function goToLogin() {
  router.replace('/login')
}

onMounted(async () => {
  await loadStatus()
})

onUnmounted(() => {
  stopCountdown()
})
</script>

<style scoped>
.bind-phone-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
  background: linear-gradient(135deg, #eff6ff 0%, #f5f3ff 100%);
}

.bind-card {
  width: 460px;
  max-width: 100%;
  padding: 32px;
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.08);
}

.bind-header {
  text-align: center;
  margin-bottom: 24px;
}

.bind-header h1 {
  margin: 0 0 8px;
  font-size: 28px;
  font-weight: 600;
  color: #111827;
}

.bind-header p {
  margin: 0;
  color: #6b7280;
  font-size: 14px;
}

.bind-state {
  min-height: 240px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  text-align: center;
  color: #6b7280;
}

.bind-state.error {
  color: #ef4444;
}

.state-icon {
  font-size: 52px;
}

.bind-form-wrap {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.bind-alert {
  margin-bottom: 4px;
}

.sms-row {
  display: grid;
  grid-template-columns: 1fr 132px;
  gap: 12px;
}

@media (max-width: 640px) {
  .bind-card {
    padding: 24px 20px;
  }

  .sms-row {
    grid-template-columns: 1fr;
  }
}
</style>
