<!-- SPEC: PJ2026-010405 云端控制台. -->
<!-- Implementation reference: draft-2026-07-13-p0-cloud-console. -->
<script setup lang="ts">
import { computed, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useAuthStore } from "@/stores/auth";

const auth = useAuthStore();
const route = useRoute();
const router = useRouter();

const email = ref("");
const username = ref("");
const displayName = ref("");
const password = ref("");
const confirmPassword = ref("");
const pending = ref(false);
const localError = ref<string | null>(null);

const canSubmit = computed(() => email.value.trim() && username.value.trim() && password.value.length >= 10 && password.value === confirmPassword.value);

async function submit(): Promise<void> {
  localError.value = null;
  if (password.value.length < 10) {
    localError.value = "密码至少需要 10 个字符。";
    return;
  }
  if (password.value !== confirmPassword.value) {
    localError.value = "两次输入的密码不一致。";
    return;
  }
  pending.value = true;
  await auth.register({ email: email.value, username: username.value, displayName: displayName.value, password: password.value });
  pending.value = false;
  if (auth.isAuthenticated) await router.replace(nextPath());
}

function nextPath(): string {
  const redirect = route.query.redirect;
  return typeof redirect === "string" && redirect.startsWith("/") && !redirect.startsWith("//") ? redirect : "/workbench";
}
</script>

<template>
  <section class="login-shell">
    <section class="register-context">
      <header><span>HW</span><div><strong>HWLAB</strong><small>ACCOUNT ONBOARDING · V0.3</small></div></header>
      <div><span>IDENTITY AUTHORITY</span><h1>创建一个可审计的云端实验室身份。</h1><p>账号由 user-billing authority 写入。注册成功后仅签发 HttpOnly Web session，不把后台 token 或 Secret 交给浏览器。</p></div>
      <ol><li><span>01</span>创建身份</li><li><span>02</span>服务端建立会话</li><li><span>03</span>按 ACL 进入控制台</li></ol>
    </section>
    <section class="register-form-surface">
      <form class="login-card register-card" @submit.prevent="submit">
        <div class="register-heading"><span>CREATE ACCOUNT</span><h2>注册 HWLAB</h2><p>所有字段由服务端再次校验。</p></div>
        <div class="register-grid">
          <label>邮箱<input v-model="email" class="input" type="email" autocomplete="email" required autofocus /></label>
          <label>用户名<input v-model="username" class="input" autocomplete="username" required /></label>
          <label class="span-2">显示名<input v-model="displayName" class="input" autocomplete="name" /></label>
          <label>密码<input v-model="password" class="input" type="password" autocomplete="new-password" minlength="10" required /></label>
          <label>确认密码<input v-model="confirmPassword" class="input" type="password" autocomplete="new-password" minlength="10" required /></label>
        </div>
        <p class="password-hint">至少 10 个字符；两次输入必须一致。</p>
        <p v-if="localError || auth.error" class="form-error" role="alert">{{ localError || auth.error }}</p>
        <button class="btn btn-primary register-submit" type="submit" :disabled="pending || !canSubmit">{{ pending ? "注册中" : "注册并登录" }}</button>
        <p class="login-note">注册账号由 hwlab-user-billing 写入 PK01 PostgreSQL；浏览器仅持有 HttpOnly Web session cookie。</p>
        <RouterLink class="auth-link" to="/login">← 已有账号，返回登录</RouterLink>
      </form>
    </section>
  </section>
</template>

<style scoped>
.login-shell { display: grid; grid-template-columns: minmax(340px, .8fr) minmax(0, 1.2fr); min-height: 100dvh; background: #eef2f2; }
.register-context { display: grid; align-content: space-between; min-width: 0; background: linear-gradient(150deg, #102a32, #19424a 58%, #24565a); padding: clamp(28px, 5vw, 68px); color: #efffff; }
.register-context header { display: flex; gap: 12px; align-items: center; }
.register-context header > span { display: grid; width: 44px; height: 44px; place-items: center; border: 1px solid #76cec7; border-radius: 8px; background: rgba(27, 95, 98, .5); color: #9ee9e3; font: 850 12px/1 ui-monospace, monospace; }
.register-context header div { display: grid; gap: 4px; }
.register-context header strong { letter-spacing: 0; }
.register-context header small,
.register-context > div > span,
.register-heading > span { color: #80d3cd; font: 850 9px/1 ui-monospace, monospace; letter-spacing: 0; }
.register-context h1 { max-width: 520px; margin: 12px 0 15px; font-size: 46px; line-height: 1.06; letter-spacing: 0; }
.register-context p { max-width: 480px; margin: 0; color: #bfd5d4; font-size: 13px; line-height: 1.7; }
.register-context ol { display: grid; gap: 0; margin: 0; padding: 0; border-top: 1px solid rgba(211, 239, 237, .2); list-style: none; }
.register-context li { display: flex; gap: 10px; border-bottom: 1px solid rgba(211, 239, 237, .12); padding: 10px 0; color: #d9eeee; font-size: 11px; }
.register-context li span { color: #7ed0ca; font: 800 10px/1.3 ui-monospace, monospace; }
.register-form-surface { display: grid; place-items: center; padding: clamp(22px, 5vw, 64px); }
.login-card { display: grid; width: min(100%, 590px); gap: 15px; border: 1px solid #c6d2d7; border-radius: 8px; background: #fff; padding: clamp(24px, 4vw, 38px); box-shadow: 0 22px 60px rgba(23, 48, 55, .12), inset 3px 0 #20aaa4; }
.register-heading { display: grid; gap: 5px; margin-bottom: 5px; }
.register-heading h2 { margin: 0; color: #172c35; font-size: 25px; }
.register-heading p { margin: 0; color: #6a7981; font-size: 11px; }
.register-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.register-grid label { display: grid; gap: 6px; color: #40545d; font-size: 11px; font-weight: 800; }
.register-grid .span-2 { grid-column: 1 / -1; }
.register-grid .input { height: 40px; border-color: #aebdc5; background: #fbfcfc; }
.register-grid .input:focus { outline: 2px solid #7ecac4; outline-offset: 1px; border-color: #167d79; }
.password-hint { margin: -4px 0 0; color: #74838b; font-size: 10px; }
.register-submit { min-height: 40px; background: #173b42; }
.login-note { margin: 0; border-top: 1px solid #e1e8eb; padding-top: 12px; color: #738189; font-size: 10px; line-height: 1.5; }
.auth-link { color: #126f6b; font-size: 11px; font-weight: 800; text-decoration: none; }
@media (max-width: 880px) {
  .login-shell { grid-template-columns: 1fr; }
  .register-context { min-height: 260px; padding: 28px; }
  .register-context > div { padding: 42px 0 20px; }
  .register-context h1 { font-size: 34px; }
  .register-context ol { display: none; }
  .register-form-surface { padding: 22px; }
}
@media (max-width: 560px) {
  .register-context { min-height: 210px; }
  .register-context h1 { font-size: 28px; }
  .register-context p { display: none; }
  .register-grid { grid-template-columns: 1fr; }
  .register-grid .span-2 { grid-column: auto; }
}
</style>
