<script setup>
import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { RouterLink, useRoute, useRouter } from 'vue-router';
import { api } from '@/lib/api';
import { sessionStore } from '@/stores/session';

const props = defineProps({ mode: { type: String, required: true } });
const route = useRoute();
const router = useRouter();
const busy = ref(false);
const error = ref('');
const challenge = ref('');
const issuedNumber = ref('');
const login = reactive({ username: '', password: '', code: '' });
const register = reactive({ name: '', gender: '', schoolId: '', classId: '', password: '' });
const schools = computed(() => sessionStore.state.publicData.schools || []);
const classes = computed(() => (sessionStore.state.publicData.classes || []).filter(item => item.schoolId === register.schoolId));
const registrationEnabled = computed(() => Boolean(sessionStore.state.publicData.selfRegistrationEnabled));

async function submitLogin() {
  busy.value = true; error.value = '';
  try {
    const data = challenge.value
      ? await api('/api/auth/login/totp', { method: 'POST', body: { challenge: challenge.value, code: login.code } })
      : await api('/api/auth/login', { method: 'POST', body: { username: login.username, password: login.password } });
    if (data.requiresTotp) { challenge.value = data.challenge; return; }
    sessionStore.setSession(data);
    await sessionStore.refreshSession();
    const redirect = typeof route.query.redirect === 'string' ? route.query.redirect : sessionStore.homeFor(data.user);
    await router.replace(redirect);
  } catch (requestError) { error.value = requestError.message; }
  finally { busy.value = false; }
}

async function submitRegister() {
  busy.value = true; error.value = '';
  try {
    const data = await api('/api/auth/register', { method: 'POST', body: register });
    issuedNumber.value = data.registrationNumber;
  } catch (requestError) { error.value = requestError.message; }
  finally { busy.value = false; }
}

function syncLoginViewportLock() {
  document.documentElement.classList.toggle('auth-login-active', props.mode === 'login');
}

watch(() => props.mode, () => {
  error.value = '';
  challenge.value = '';
  issuedNumber.value = '';
  syncLoginViewportLock();
});
onMounted(syncLoginViewportLock);
onUnmounted(() => document.documentElement.classList.remove('auth-login-active'));
</script>

<template>
  <main :class="['auth-view', `auth-view--${mode}`]">
    <section class="auth-view__identity">
      <RouterLink class="app-brand app-brand--light" to="/"><span>衡</span><div><strong>衡准考试服务</strong><small>EXAMINATION INFORMATION SERVICE</small></div></RouterLink>
      <div><p>CANDIDATE SERVICE</p><h1><template v-if="mode === 'login'"><span>一个报名号，</span><span>办理每一次考试。</span></template><template v-else><span>申请长期使用的</span><span>固定报名号。</span></template></h1><span>报名号就是考生账户，不因考试、科目或年度报名而改变。</span></div>
      <small>统一身份 · 全程留痕 · 文书可核验</small>
    </section>
    <section class="auth-view__panel">
      <RouterLink class="auth-view__back" to="/">← 返回首页</RouterLink>
      <form v-if="mode === 'login'" class="auth-card" @submit.prevent="submitLogin">
        <p>{{ challenge ? 'SECOND STEP' : 'ACCOUNT LOGIN' }}</p>
        <h2>{{ challenge ? '输入动态验证码' : '报名号登录' }}</h2>
        <span>{{ challenge ? '输入验证器当前显示的 6 位验证码，或使用一个恢复码。' : '考生填写报名号和密码；管理员使用管理账号。' }}</span>
        <div v-if="error" class="form-error">{{ error }}</div>
        <template v-if="!challenge"><label><span>报名号 / 管理员账号</span><input v-model="login.username" autocomplete="username" required></label><label><span>密码</span><input v-model="login.password" type="password" autocomplete="current-password" required></label></template>
        <label v-else><span>动态验证码或恢复码</span><input v-model="login.code" autocomplete="one-time-code" required autofocus></label>
        <button class="app-button app-button--primary app-button--large" type="submit" :disabled="busy">{{ busy ? '正在处理…' : challenge ? '验证并登录' : '登录系统' }}</button>
        <button v-if="challenge" class="app-link-button" type="button" @click="challenge = ''; login.code = ''">返回账号密码登录</button>
        <p v-if="registrationEnabled" class="auth-card__switch">还没有报名号？<RouterLink to="/auth/register">在线申请</RouterLink></p>
      </form>
      <form v-else-if="registrationEnabled && !issuedNumber" class="auth-card" @submit.prevent="submitRegister">
        <p>CANDIDATE NUMBER</p><h2>申请固定报名号</h2><span>提交基础学籍范围后，系统会生成长期使用的报名号。</span>
        <div v-if="error" class="form-error">{{ error }}</div>
        <div class="form-grid"><label><span>考生姓名</span><input v-model="register.name" required></label><label><span>性别</span><select v-model="register.gender" required><option value="">请选择</option><option>男</option><option>女</option></select></label><label><span>就读学校</span><select v-model="register.schoolId" required @change="register.classId = ''"><option value="">请选择</option><option v-for="school in schools" :key="school.id" :value="school.id">{{ school.name }}</option></select></label><label><span>班级</span><select v-model="register.classId" required><option value="">请选择</option><option v-for="item in classes" :key="item.id" :value="item.id">{{ item.name }}</option></select></label></div>
        <label><span>设置登录密码</span><input v-model="register.password" type="password" minlength="8" required></label>
        <button class="app-button app-button--primary app-button--large" type="submit" :disabled="busy">{{ busy ? '正在生成…' : '生成我的报名号' }}</button>
        <p class="auth-card__switch">已有报名号？<RouterLink to="/auth/login">返回登录</RouterLink></p>
      </form>
      <section v-else-if="issuedNumber" class="auth-card issued-card"><p>CANDIDATE NUMBER</p><h2>请保存你的报名号</h2><strong>{{ issuedNumber }}</strong><span>以后报名不同考试仍使用这个号码，请立即抄写并安全保存。</span><RouterLink class="app-button app-button--primary app-button--large" to="/auth/login">前往登录</RouterLink></section>
      <section v-else class="auth-card"><p>REGISTRATION CLOSED</p><h2>自主注册暂未开放</h2><span>请联系学校领取报名号和初始密码。</span><RouterLink class="app-button app-button--primary app-button--large" to="/auth/login">返回登录</RouterLink></section>
    </section>
  </main>
</template>
