<script setup>
import { computed, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'

import { fetchEmailVerifyStatus, generateCaptcha, register } from '../api/auth'
import { validateStrongPassword } from '../utils/password'

const router = useRouter()

const form = reactive({
  username: '',
  password: '',
  confirm_password: '',
  email: '',
  captcha: '',
})

const emailVerifyEnabled = ref(false)
const captchaImage = ref('')
const captchaSession = ref('')
const loading = ref(false)

const errorText = ref('')
const successTitle = ref('')
const successDesc = ref('')

const socialPendingKeys = {
  token: 'zsglpt_social_pending_bind_token',
  provider: 'zsglpt_social_pending_bind_provider',
  nickname: 'zsglpt_social_pending_bind_nickname',
  avatar: 'zsglpt_social_pending_bind_avatar_url',
}

const providerLabels = {
  qq: 'QQ',
  wx: '微信',
  alipay: '支付宝',
}

const pendingSocial = reactive({
  token: '',
  provider: '',
  nickname: '',
  avatar_url: '',
})

const emailLabel = computed(() => (emailVerifyEnabled.value ? '邮箱 *' : '邮箱（可选）'))
const emailHint = computed(() => (emailVerifyEnabled.value ? '必填，用于账号验证' : '选填，用于找回密码和接收通知'))

async function refreshCaptcha() {
  try {
    const data = await generateCaptcha()
    captchaSession.value = data?.session_id || ''
    captchaImage.value = data?.captcha_image || ''
    form.captcha = ''
  } catch {
    captchaSession.value = ''
    captchaImage.value = ''
  }
}

async function loadEmailVerifyStatus() {
  try {
    const data = await fetchEmailVerifyStatus()
    emailVerifyEnabled.value = Boolean(data?.register_verify_enabled)
  } catch {
    emailVerifyEnabled.value = false
  }
}

function clearAlerts() {
  errorText.value = ''
  successTitle.value = ''
  successDesc.value = ''
}

function loadPendingSocialBind() {
  try {
    pendingSocial.token = window.sessionStorage.getItem(socialPendingKeys.token) || ''
    pendingSocial.provider = window.sessionStorage.getItem(socialPendingKeys.provider) || ''
    pendingSocial.nickname = window.sessionStorage.getItem(socialPendingKeys.nickname) || ''
    pendingSocial.avatar_url = window.sessionStorage.getItem(socialPendingKeys.avatar) || ''
    if (pendingSocial.nickname && !form.username) {
      form.username = pendingSocial.nickname.replace(/[^\w\u4e00-\u9fa5]/g, '').slice(0, 20)
    }
  } catch {
    pendingSocial.token = ''
    pendingSocial.provider = ''
    pendingSocial.nickname = ''
    pendingSocial.avatar_url = ''
  }
}

function clearPendingSocialBind() {
  try {
    Object.values(socialPendingKeys).forEach((key) => window.sessionStorage.removeItem(key))
  } catch {
    // ignore storage failures
  }
  pendingSocial.token = ''
  pendingSocial.provider = ''
  pendingSocial.nickname = ''
  pendingSocial.avatar_url = ''
}

async function onSubmit() {
  clearAlerts()

  const username = form.username.trim()
  const password = form.password
  const confirmPassword = form.confirm_password
  const email = form.email.trim()
  const captcha = form.captcha.trim()

  if (username.length < 3) {
    errorText.value = '用户名至少3个字符'
    ElMessage.error(errorText.value)
    return
  }
  const passwordCheck = validateStrongPassword(password)
  if (!passwordCheck.ok) {
    errorText.value = passwordCheck.message || '密码格式不正确'
    ElMessage.error(errorText.value)
    return
  }
  if (password !== confirmPassword) {
    errorText.value = '两次输入的密码不一致'
    ElMessage.error(errorText.value)
    return
  }
  if (emailVerifyEnabled.value && !email) {
    errorText.value = '请填写邮箱地址用于账号验证'
    ElMessage.error(errorText.value)
    return
  }
  if (email && !email.includes('@')) {
    errorText.value = '邮箱格式不正确'
    ElMessage.error(errorText.value)
    return
  }
  if (!captcha) {
    errorText.value = '请输入验证码'
    ElMessage.error(errorText.value)
    return
  }

  loading.value = true
  try {
    const res = await register({
      username,
      password,
      email,
      captcha_session: captchaSession.value,
      captcha,
      social_bind_token: pendingSocial.token || undefined,
    })

    successTitle.value = res?.message || '注册成功'
    successDesc.value = res?.need_verify ? '请检查您的邮箱（包括垃圾邮件文件夹）' : ''
    ElMessage.success('注册成功')
    if (pendingSocial.token) {
      clearPendingSocialBind()
    }

    form.username = ''
    form.password = ''
    form.confirm_password = ''
    form.email = ''
    form.captcha = ''

    setTimeout(() => {
      window.location.href = '/login'
    }, 3000)
  } catch (e) {
    const data = e?.response?.data
    errorText.value = data?.error || '注册失败'
    ElMessage.error(errorText.value)
    await refreshCaptcha()
  } finally {
    loading.value = false
  }
}

function goLogin() {
  router.push('/login')
}

onMounted(async () => {
  loadPendingSocialBind()
  await refreshCaptcha()
  await loadEmailVerifyStatus()
})
</script>

<template>
  <div class="auth-wrap">
    <el-card shadow="never" class="auth-card" :body-style="{ padding: '22px' }">
      <div class="brand">
        <div class="brand-title">知识管理平台</div>
        <div class="brand-sub app-muted">用户注册</div>
      </div>

      <el-alert v-if="errorText" type="error" :closable="false" :title="errorText" show-icon class="alert" />
      <el-alert
        v-if="successTitle"
        type="success"
        :closable="false"
        :title="successTitle"
        :description="successDesc"
        show-icon
        class="alert"
      />

      <el-alert
        v-if="pendingSocial.token"
        type="info"
        :closable="false"
        show-icon
        class="alert"
        :title="`注册后绑定${providerLabels[pendingSocial.provider] || '快捷登录'}`"
      />

      <el-form label-position="top">
        <el-form-item label="用户名 *">
          <el-input v-model="form.username" placeholder="至少3个字符" autocomplete="username" />
          <div class="hint app-muted">至少3个字符</div>
        </el-form-item>
        <el-form-item label="密码 *">
          <el-input
            v-model="form.password"
            type="password"
            show-password
            placeholder="至少8位且包含字母和数字"
            autocomplete="new-password"
          />
          <div class="hint app-muted">至少8位且包含字母和数字</div>
        </el-form-item>
        <el-form-item label="确认密码 *">
          <el-input
            v-model="form.confirm_password"
            type="password"
            show-password
            placeholder="请再次输入密码"
            autocomplete="new-password"
            @keyup.enter="onSubmit"
          />
        </el-form-item>
        <el-form-item :label="emailLabel">
          <el-input v-model="form.email" placeholder="name@example.com" autocomplete="email" />
          <div class="hint app-muted">{{ emailHint }}</div>
        </el-form-item>
        <el-form-item label="验证码 *">
          <div class="captcha-row">
            <el-input v-model="form.captcha" placeholder="请输入验证码" @keyup.enter="onSubmit" />
            <img
              v-if="captchaImage"
              class="captcha-img"
              :src="captchaImage"
              alt="验证码"
              title="点击刷新"
              @click="refreshCaptcha"
            />
            <el-button @click="refreshCaptcha">刷新</el-button>
          </div>
        </el-form-item>
      </el-form>

      <el-button type="primary" class="submit-btn" :loading="loading" @click="onSubmit">注册</el-button>

      <div class="actions">
        <span class="app-muted">已有账号？</span>
        <el-button link type="primary" @click="goLogin">立即登录</el-button>
      </div>
    </el-card>
  </div>
</template>

<style scoped>
.auth-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.auth-card {
  width: 100%;
  max-width: 420px;
  border-radius: var(--app-radius);
  border: 1px solid var(--app-border);
  box-shadow: var(--app-shadow);
}

.brand {
  margin-bottom: 14px;
}

.brand-title {
  font-size: 18px;
  font-weight: 900;
}

.brand-sub {
  margin-top: 4px;
  font-size: 12px;
}

.alert {
  margin-bottom: 12px;
}

.hint {
  margin-top: 6px;
  font-size: 12px;
}

.captcha-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
}

.captcha-img {
  height: 40px;
  border: 1px solid var(--app-border);
  border-radius: 8px;
  cursor: pointer;
  user-select: none;
}

.submit-btn {
  width: 100%;
  margin-top: 4px;
}

.actions {
  margin-top: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
</style>
