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

import {
  fetchEmailVerifyStatus,
  forgotPassword,
  generateCaptcha,
  login,
  resendVerifyEmail,
} from '../api/auth'

const router = useRouter()

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

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

const emailEnabled = ref(false)
const registerVerifyEnabled = ref(false)

const forgotOpen = ref(false)
const resendOpen = ref(false)

const forgotForm = reactive({
  username: '',
  captcha: '',
})
const forgotCaptchaImage = ref('')
const forgotCaptchaSession = ref('')
const forgotLoading = ref(false)
const forgotHint = ref('')

const resendForm = reactive({
  email: '',
  captcha: '',
})
const resendCaptchaImage = ref('')
const resendCaptchaSession = ref('')
const resendLoading = ref(false)

const showResendLink = computed(() => Boolean(registerVerifyEnabled.value))

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

async function refreshEmailResetCaptcha() {
  try {
    const data = await generateCaptcha()
    forgotCaptchaSession.value = data?.session_id || ''
    forgotCaptchaImage.value = data?.captcha_image || ''
    forgotForm.captcha = ''
  } catch {
    forgotCaptchaSession.value = ''
    forgotCaptchaImage.value = ''
  }
}

async function refreshResendCaptcha() {
  try {
    const data = await generateCaptcha()
    resendCaptchaSession.value = data?.session_id || ''
    resendCaptchaImage.value = data?.captcha_image || ''
    resendForm.captcha = ''
  } catch {
    resendCaptchaSession.value = ''
    resendCaptchaImage.value = ''
  }
}

async function onSubmit() {
  if (!form.username.trim() || !form.password.trim()) {
    ElMessage.error('用户名和密码不能为空')
    return
  }
  if (needCaptcha.value && !form.captcha.trim()) {
    ElMessage.error('请输入验证码')
    return
  }

  loading.value = true
  try {
    await login({
      username: form.username.trim(),
      password: form.password,
      captcha_session: captchaSession.value,
      captcha: form.captcha.trim(),
      need_captcha: needCaptcha.value,
    })
    ElMessage.success('登录成功，正在跳转...')
    const urlParams = new URLSearchParams(window.location.search || '')
    const next = String(urlParams.get('next') || '').trim()
    const safeNext = next && next.startsWith('/') && !next.startsWith('//') && !next.startsWith('/\\') ? next : ''
    setTimeout(() => {
      const target = safeNext || '/app'
      router.push(target).catch(() => {
        window.location.href = target
      })
    }, 300)
  } catch (e) {
    const status = e?.response?.status
    const data = e?.response?.data
    const message = data?.error || data?.message || '登录失败'

    ElMessage.error(message)

    if (data?.need_captcha) {
      needCaptcha.value = true
      await refreshLoginCaptcha()
    } else if (needCaptcha.value && status === 400) {
      await refreshLoginCaptcha()
    }
  } finally {
    loading.value = false
  }
}

async function openForgot() {
  forgotOpen.value = true
  forgotHint.value = ''
  forgotForm.username = ''
  forgotForm.captcha = ''
  if (emailEnabled.value) {
    await refreshEmailResetCaptcha()
  }
}

async function submitForgot() {
  forgotHint.value = ''

  if (!emailEnabled.value) {
    ElMessage.warning('邮件功能未启用，请联系管理员重置密码。')
    return
  }

  const username = forgotForm.username.trim()
  if (!username) {
    ElMessage.error('请输入用户名')
    return
  }
  if (!forgotForm.captcha.trim()) {
    ElMessage.error('请输入验证码')
    return
  }

  forgotLoading.value = true
  try {
    const res = await forgotPassword({
      username,
      captcha_session: forgotCaptchaSession.value,
      captcha: forgotForm.captcha.trim(),
    })
    ElMessage.success(res?.message || '已发送重置邮件')
    setTimeout(() => {
      forgotOpen.value = false
    }, 800)
  } catch (e) {
    const data = e?.response?.data
    const message = data?.error || '发送失败'
    if (data?.code === 'email_not_bound') {
      forgotHint.value = message
    } else {
      ElMessage.error(message)
    }
    await refreshEmailResetCaptcha()
  } finally {
    forgotLoading.value = false
  }
}

async function openResend() {
  resendOpen.value = true
  resendForm.email = ''
  resendForm.captcha = ''
  await refreshResendCaptcha()
}

async function submitResend() {
  const email = resendForm.email.trim()
  if (!email) {
    ElMessage.error('请输入邮箱')
    return
  }
  if (!resendForm.captcha.trim()) {
    ElMessage.error('请输入验证码')
    return
  }

  resendLoading.value = true
  try {
    const res = await resendVerifyEmail({
      email,
      captcha_session: resendCaptchaSession.value,
      captcha: resendForm.captcha.trim(),
    })
    ElMessage.success(res?.message || '验证邮件已发送，请查收')
    setTimeout(() => {
      resendOpen.value = false
    }, 800)
  } catch (e) {
    const data = e?.response?.data
    ElMessage.error(data?.error || '发送失败')
    await refreshResendCaptcha()
  } finally {
    resendLoading.value = false
  }
}

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

onMounted(async () => {
  try {
    const status = await fetchEmailVerifyStatus()
    emailEnabled.value = Boolean(status?.email_enabled)
    registerVerifyEnabled.value = Boolean(status?.register_verify_enabled)
  } catch {
    emailEnabled.value = false
    registerVerifyEnabled.value = false
  }
})
</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-form label-position="top">
        <el-form-item label="用户名">
          <el-input v-model="form.username" placeholder="请输入用户名" autocomplete="username" />
        </el-form-item>
        <el-form-item label="密码">
          <el-input
            v-model="form.password"
            type="password"
            show-password
            placeholder="请输入密码"
            autocomplete="current-password"
            @keyup.enter="onSubmit"
          />
        </el-form-item>

        <el-form-item v-if="needCaptcha" 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="refreshLoginCaptcha"
            />
            <el-button @click="refreshLoginCaptcha">刷新</el-button>
          </div>
        </el-form-item>
      </el-form>

      <div class="links">
        <el-button text type="primary" @click="openForgot">忘记密码？</el-button>
        <el-button v-if="showResendLink" text type="primary" @click="openResend">重发验证邮件</el-button>
      </div>

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

      <div class="foot">
        <span class="app-muted">还没有账号？</span>
        <el-button link type="primary" @click="goRegister">立即注册</el-button>
      </div>
    </el-card>

    <el-dialog v-model="forgotOpen" title="找回密码" width="min(560px, 92vw)">
      <el-alert
        v-if="!emailEnabled"
        type="warning"
        :closable="false"
        title="邮件功能未启用"
        description="无法通过邮箱找回密码，请联系管理员重置密码。"
        show-icon
      />
      <el-alert
        v-else
        type="info"
        :closable="false"
        title="通过邮箱找回密码"
        description="输入用户名并完成验证码，我们将向该账号绑定的邮箱发送重置链接。"
        show-icon
      />
      <el-alert
        v-if="forgotHint"
        type="warning"
        :closable="false"
        title="无法通过邮箱找回密码"
        :description="forgotHint"
        show-icon
        class="alert"
      />
      <el-form label-position="top" class="dialog-form">
        <el-form-item label="用户名">
          <el-input v-model="forgotForm.username" placeholder="请输入用户名" />
        </el-form-item>
        <el-form-item label="验证码">
          <div class="captcha-row">
            <el-input v-model="forgotForm.captcha" placeholder="请输入验证码" />
            <img
              v-if="forgotCaptchaImage"
              class="captcha-img"
              :src="forgotCaptchaImage"
              alt="验证码"
              title="点击刷新"
              @click="refreshEmailResetCaptcha"
            />
            <el-button @click="refreshEmailResetCaptcha">刷新</el-button>
          </div>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="forgotOpen = false">取消</el-button>
        <el-button type="primary" :loading="forgotLoading" :disabled="!emailEnabled" @click="submitForgot">
          发送重置邮件
        </el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="resendOpen" title="重发验证邮件" width="min(520px, 92vw)">
      <el-alert type="info" :closable="false" title="用于注册邮箱验证：请输入邮箱并完成验证码。" show-icon />
      <el-form label-position="top" class="dialog-form">
        <el-form-item label="邮箱">
          <el-input v-model="resendForm.email" placeholder="name@example.com" />
        </el-form-item>
        <el-form-item label="验证码">
          <div class="captcha-row">
            <el-input v-model="resendForm.captcha" placeholder="请输入验证码" />
            <img
              v-if="resendCaptchaImage"
              class="captcha-img"
              :src="resendCaptchaImage"
              alt="验证码"
              title="点击刷新"
              @click="refreshResendCaptcha"
            />
            <el-button @click="refreshResendCaptcha">刷新</el-button>
          </div>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="resendOpen = false">取消</el-button>
        <el-button type="primary" :loading="resendLoading" @click="submitResend">发送</el-button>
      </template>
    </el-dialog>
  </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;
}

.links {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 2px 0 10px;
  flex-wrap: wrap;
}

.submit-btn {
  width: 100%;
}

.foot {
  margin-top: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.dialog-form {
  margin-top: 10px;
}

.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;
}

@media (max-width: 480px) {
  .captcha-img {
    height: 38px;
  }
}
</style>
