<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import * as api from '@/api'
import { useAuthStore } from '@/stores/auth'
import type { Captcha } from '@/api/types'

const router = useRouter()
const auth = useAuthStore()

const tab = ref<'admin' | 'user'>('admin')
const loading = ref(false)

// 管理员登录
const adminForm = reactive({ username: '', password: '' })

// 外部用户 OTP 登录
const userForm = reactive({ username: '', code: '', captcha_id: '', captcha_code: '' })
const captcha = ref<Captcha | null>(null)
const captchaLoading = ref(false)
const cooldown = ref(0) // OTP 发送冷却倒计时（秒）
let cooldownTimer: number | undefined

async function loadCaptcha() {
  captchaLoading.value = true
  try {
    captcha.value = await api.getCaptcha()
  } catch {
    captcha.value = null
  } finally {
    captchaLoading.value = false
  }
}

function startCooldown(secs: number) {
  cooldown.value = secs
  cooldownTimer = window.setInterval(() => {
    cooldown.value -= 1
    if (cooldown.value <= 0) {
      window.clearInterval(cooldownTimer)
      cooldown.value = 0
    }
  }, 1000)
}

async function onAdminLogin() {
  if (!adminForm.username || !adminForm.password) {
    ElMessage.warning('请输入用户名和密码')
    return
  }
  loading.value = true
  try {
    await api.adminLogin(adminForm)
    await auth.fetchMe()
    router.push('/admin/dashboard')
  } catch {
    // 错误已由拦截器提示
  } finally {
    loading.value = false
  }
}

async function onSendOtp() {
  if (!userForm.username || !userForm.captcha_code) {
    ElMessage.warning('请输入用户名和图形验证码')
    return
  }
  if (!captcha.value) {
    await loadCaptcha()
    if (!captcha.value) return
  }
  try {
    await api.otpSend({
      username: userForm.username,
      captcha_id: captcha.value.captcha_id,
      captcha_code: userForm.captcha_code,
    })
    ElMessage.success('验证码已发送（邮件或 CLI：usernode user otp）')
    startCooldown(60)
    // 验证码一次性，重新生成
    userForm.captcha_code = ''
    await loadCaptcha()
  } catch {
    // 验证码错误等已提示；重新生成一次
    await loadCaptcha()
  }
}

async function onUserLogin() {
  if (!userForm.username || !userForm.code) {
    ElMessage.warning('请输入用户名和 OTP 验证码')
    return
  }
  loading.value = true
  try {
    await api.otpLogin({ username: userForm.username, code: userForm.code })
    await auth.fetchMe()
    router.push('/me/profile')
  } catch {
    // 已提示
  } finally {
    loading.value = false
  }
}

function onTabChange() {
  if (tab.value === 'user' && !captcha.value) {
    loadCaptcha()
  }
}

onMounted(() => {
  if (tab.value === 'user') loadCaptcha()
})
</script>

<template>
  <div class="login-page">
    <el-card class="login-card" shadow="always">
      <div class="brand">
        <el-icon :size="30"><Monitor /></el-icon>
        <h2>服务器用户管理节点</h2>
      </div>

      <el-tabs v-model="tab" stretch @tab-change="onTabChange">
        <!-- 管理员登录 -->
        <el-tab-pane label="管理员登录" name="admin">
          <el-form label-position="top" @submit.prevent="onAdminLogin">
            <el-form-item label="用户名">
              <el-input v-model="adminForm.username" placeholder="管理员用户名" autocomplete="username" />
            </el-form-item>
            <el-form-item label="密码">
              <el-input
                v-model="adminForm.password"
                type="password"
                placeholder="密码"
                show-password
                autocomplete="current-password"
                @keyup.enter="onAdminLogin"
              />
            </el-form-item>
            <el-button type="primary" class="submit" :loading="loading" @click="onAdminLogin">登录</el-button>
          </el-form>
        </el-tab-pane>

        <!-- 外部用户 OTP 登录 -->
        <el-tab-pane label="外部用户登录" name="user">
          <el-form label-position="top" @submit.prevent="onUserLogin">
            <el-form-item label="用户名">
              <el-input v-model="userForm.username" placeholder="用户名（可带或不带 ext_ 前缀）" autocomplete="username" />
            </el-form-item>
            <el-form-item label="图形验证码">
              <div class="captcha-row">
                <el-input v-model="userForm.captcha_code" placeholder="4 位验证码" maxlength="4" @keyup.enter="onSendOtp" />
                <el-image
                  v-if="captcha"
                  :src="captcha.image"
                  fit="contain"
                  class="captcha-img"
                  :title="'点击刷新'"
                  @click="loadCaptcha"
                />
                <el-button v-else :loading="captchaLoading" @click="loadCaptcha">获取</el-button>
              </div>
            </el-form-item>
            <el-form-item label="登录验证码（OTP）">
              <el-input
                v-model="userForm.code"
                placeholder="6 位 OTP（邮件或 CLI 获取）"
                maxlength="6"
                @keyup.enter="onUserLogin"
              />
            </el-form-item>
            <el-button type="primary" class="submit" :loading="loading" @click="onSendOtp" :disabled="cooldown > 0">
              {{ cooldown > 0 ? `重新发送（${cooldown}s）` : '发送验证码' }}
            </el-button>
            <el-button type="success" class="submit" :loading="loading" @click="onUserLogin">登录</el-button>
          </el-form>
        </el-tab-pane>
      </el-tabs>

      <div class="foot">
        <router-link to="/apply">申请新账号</router-link>
      </div>
    </el-card>
  </div>
</template>

<style scoped>
.login-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #1f2d3d 0%, #2c3e50 100%);
}
.login-card {
  width: 400px;
  border-radius: 8px;
}
.brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 8px;
}
.brand h2 {
  margin: 0;
  font-size: 18px;
}
.captcha-row {
  display: flex;
  gap: 8px;
  width: 100%;
}
.captcha-img {
  width: 110px;
  height: 32px;
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
  cursor: pointer;
  flex-shrink: 0;
}
.submit {
  width: 100%;
  margin-top: 4px;
}
.foot {
  margin-top: 16px;
  text-align: center;
  font-size: 13px;
}
</style>
