﻿<template>
  <div class="page-login">
    <div class="login-orb login-orb-a"></div>
    <div class="login-orb login-orb-b"></div>

    <div class="login-shell">
      <section class="login-hero">
        <p class="hero-kicker">SEA TIME</p>
        <h1>欢迎回到航海时代</h1>
        <p class="hero-copy">
          这是一套移动端登录页示例，保留 Vant 的按钮与标签组件，表单主体改为 SSR 稳定写法。
        </p>

        <div class="hero-pills">
          <span>移动端优先</span>
          <span>SSR 安全</span>
          <span>模拟登录</span>
        </div>
      </section>

      <section class="login-card">
        <div class="card-top">
          <div>
            <p class="card-eyebrow">账号登录</p>
            <h2>继续你的航程</h2>
          </div>
          <van-tag round plain type="primary">Sample</van-tag>
        </div>

        <div class="card-banner">
          <span class="banner-dot"></span>
          默认可直接使用演示账号，也可以手动输入任意符合规则的内容。
        </div>

        <div class="demo-account">
          <div>
            <strong>演示账号</strong>
            <span>captain</span>
          </div>
          <div>
            <strong>演示密码</strong>
            <span>Voyage123</span>
          </div>
        </div>

        <form class="login-form" novalidate @submit.prevent="handleSubmit">
          <div class="field-group">
            <label class="field-label" for="login-username">账号</label>
            <div class="field-box" :class="{ 'is-error': !!errors.username }">
              <span class="field-marker">A</span>
              <input id="login-username" v-model.trim="form.username" class="field-input" type="text" inputmode="text"
                autocomplete="username" placeholder="请输入账号" @input="clearFieldError('username')" />
            </div>
            <p v-if="errors.username" class="field-error">{{ errors.username }}</p>
          </div>

          <div class="field-group">
            <label class="field-label" for="login-password">密码</label>
            <div class="field-box" :class="{ 'is-error': !!errors.password }">
              <span class="field-marker">P</span>
              <input id="login-password" v-model.trim="form.password" class="field-input" type="password"
                autocomplete="current-password" placeholder="请输入密码" @input="clearFieldError('password')" />
            </div>
            <p v-if="errors.password" class="field-error">{{ errors.password }}</p>
          </div>

          <div class="login-options">
            <label class="check-row">
              <input v-model="form.remember" class="check-input" type="checkbox" />
              <span class="check-box"></span>
              <span class="check-text">记住演示账号</span>
            </label>

            <button class="ghost-link" type="button" @click="fillDemoAccount">一键填充</button>
            <van-button type="primary" to="/home" size="mini" :loading="false">路由跳转</van-button>
          </div>

          <div class="login-agreement">
            <label class="check-row">
              <input v-model="form.agreement" class="check-input" type="checkbox"
                @change="clearFieldError('agreement')" />
              <span class="check-box"></span>
              <span class="check-text">我已阅读并同意演示使用说明</span>
            </label>
            <p v-if="errors.agreement" class="field-error agreement-error">{{ errors.agreement }}</p>
          </div>

          <div class="login-actions">
            <van-button block round type="primary" native-type="submit" :loading="isSubmitting"
              :disabled="submitDisabled">
              模拟登录
            </van-button>
            <van-button block round plain type="primary" native-type="button" @click="clearForm">
              清空输入
            </van-button>
          </div>
        </form>

        <div class="login-tips">
          <div class="tip-item">
            <span>01</span>
            去掉 ClientOnly，刷新时不再有表单占位替换。
          </div>
          <div class="tip-item">
            <span>02</span>
            提交后延迟模拟请求，并跳转到主页。
          </div>
        </div>
      </section>
    </div>

  </div>

</template>

<script setup lang="ts">
definePageMeta({
  layout: layout.empty
})

type ErrorField = 'username' | 'password' | 'agreement'

const isSubmitting = ref(false)

const form = reactive({
  username: '',
  password: '',
  remember: true,
  agreement: true
})

const errors = reactive<Record<ErrorField, string>>({
  username: '',
  password: '',
  agreement: ''
})

const submitDisabled = computed(() => {
  return !form.username.trim() || !form.password.trim() || !form.agreement
})

const clearFieldError = (field: ErrorField) => {
  errors[field] = ''
}

const validateForm = () => {
  errors.username = ''
  errors.password = ''
  errors.agreement = ''

  if (!form.username.trim()) {
    errors.username = '请输入账号'
  } else if (form.username.trim().length < 3) {
    errors.username = '账号至少 3 位'
  }

  if (!form.password.trim()) {
    errors.password = '请输入密码'
  } else if (form.password.trim().length < 6) {
    errors.password = '密码至少 6 位'
  }

  if (!form.agreement) {
    errors.agreement = '请先勾选使用说明'
  }

  return !errors.username && !errors.password && !errors.agreement
}

const fillDemoAccount = () => {
  form.username = 'captain'
  form.password = 'Voyage123'
  errors.username = ''
  errors.password = ''
  showToast('已填充演示账号')
}

const clearForm = () => {
  form.username = ''
  form.password = ''
  form.agreement = true
  errors.username = ''
  errors.password = ''
  errors.agreement = ''
  showToast('已清空输入')
}

const handleSubmit = async () => {
  if (!validateForm()) {
    showFailToast(Object.values(errors).find(Boolean) || '请检查表单内容')
    return
  }

  try {
    isSubmitting.value = true
    await new Promise((resolve) => setTimeout(resolve, 900))
    showSuccessToast('登录成功')
    await navigateTo('/home')
  } finally {
    isSubmitting.value = false
  }
}
</script>

<style scoped>
.page-login {
  position: relative;
  overflow: hidden;
  min-height: 100vh;
  padding: 28px 16px 40px;
  background:
    linear-gradient(180deg, #0b3558 0%, #0f2943 46%, #f4f8fc 46%, #f4f8fc 100%);
}

.login-orb {
  position: absolute;
  border-radius: 999px;
  filter: blur(4px);
  pointer-events: none;
}

.login-orb-a {
  top: -36px;
  right: -22px;
  width: 148px;
  height: 148px;
  background: radial-gradient(circle, rgba(103, 232, 249, 0.56), rgba(103, 232, 249, 0));
}

.login-orb-b {
  top: 168px;
  left: -52px;
  width: 180px;
  height: 180px;
  background: radial-gradient(circle, rgba(96, 165, 250, 0.24), rgba(96, 165, 250, 0));
}

.login-shell {
  position: relative;
  z-index: 1;
  max-width: 420px;
  margin: 0 auto;
}

.login-hero {
  padding: 8px 6px 24px;
  color: #f8fbff;
}

.hero-kicker {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.28em;
  color: rgba(186, 230, 253, 0.92);
}

.login-hero h1 {
  margin: 0;
  font-size: 34px;
  line-height: 1.08;
  letter-spacing: 0.01em;
}

.hero-copy {
  margin: 14px 0 0;
  font-size: 14px;
  line-height: 1.7;
  color: rgba(226, 232, 240, 0.92);
}

.hero-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}

.hero-pills span {
  padding: 6px 10px;
  border: 1px solid rgba(186, 230, 253, 0.18);
  border-radius: 999px;
  font-size: 12px;
  color: #dbeafe;
  background: rgba(255, 255, 255, 0.1);
}

.login-card {
  margin-top: 8px;
  padding: 22px 16px 18px;
  border-radius: 28px;
  background: #ffffff;
  box-shadow: 0 28px 60px rgba(15, 23, 42, 0.14);
}

.card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.card-eyebrow {
  margin: 0 0 6px;
  font-size: 12px;
  color: #64748b;
}

.card-top h2 {
  margin: 0;
  font-size: 24px;
  color: #0f172a;
}

.card-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: 16px;
  font-size: 13px;
  line-height: 1.6;
  color: #0f3d62;
  background: linear-gradient(135deg, #e0f2fe, #eff6ff);
}

.banner-dot {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: linear-gradient(135deg, #0ea5e9, #2563eb);
  box-shadow: 0 0 0 4px rgba(14, 165, 233, 0.12);
}

.demo-account {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-top: 14px;
}

.demo-account div {
  padding: 12px 14px;
  border-radius: 18px;
  background: #f8fafc;
}

.demo-account strong,
.demo-account span {
  display: block;
}

.demo-account strong {
  margin-bottom: 6px;
  font-size: 12px;
  color: #64748b;
}

.demo-account span {
  font-size: 15px;
  font-weight: 700;
  color: #0f172a;
}

.login-form {
  margin-top: 18px;
}

.field-group+.field-group {
  margin-top: 14px;
}

.field-label {
  display: block;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 600;
  color: #334155;
}

.field-box {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  padding: 0 14px;
  border: 1px solid #dbe4f0;
  border-radius: 18px;
  background: #f8fafc;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.field-box:focus-within {
  border-color: #3b82f6;
  background: #ffffff;
  box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
}

.field-box.is-error {
  border-color: #f87171;
}

.field-marker {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 700;
  color: #2563eb;
  background: #dbeafe;
}

.field-input {
  flex: 1;
  width: 100%;
  min-width: 0;
  border: 0;
  background: transparent;
  color: #0f172a;
}

.field-input::placeholder {
  color: #94a3b8;
}

.field-input:-webkit-autofill,
.field-input:-webkit-autofill:hover,
.field-input:-webkit-autofill:focus {
  -webkit-text-fill-color: #0f172a;
  box-shadow: 0 0 0 1000px #f8fafc inset;
}

.field-error {
  margin: 6px 0 0;
  font-size: 12px;
  color: #dc2626;
}

.login-options,
.login-agreement {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 2px 0;
}

.login-agreement {
  display: block;
  padding-top: 12px;
}

.agreement-error {
  margin-left: 32px;
}

.check-row {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: #475569;
}

.check-input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.check-box {
  position: relative;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border: 1.5px solid #cbd5e1;
  border-radius: 6px;
  background: #ffffff;
  transition: all 0.2s ease;
}

.check-box::after {
  content: '';
  position: absolute;
  top: 1px;
  left: 5px;
  width: 4px;
  height: 9px;
  border-right: 2px solid #ffffff;
  border-bottom: 2px solid #ffffff;
  opacity: 0;
  transform: rotate(45deg);
}

.check-input:checked+.check-box {
  border-color: #2563eb;
  background: #2563eb;
}

.check-input:checked+.check-box::after {
  opacity: 1;
}

.check-text {
  font-size: 13px;
  line-height: 1.5;
}

.ghost-link {
  padding: 0;
  border: 0;
  color: #2563eb;
  background: transparent;
  appearance: none;
  -webkit-appearance: none;
}

.login-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 18px;
}

.login-tips {
  display: grid;
  gap: 10px;
  margin-top: 18px;
}

.tip-item {
  display: flex;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 16px;
  font-size: 13px;
  line-height: 1.6;
  color: #334155;
  background: #f8fafc;
}

.tip-item span {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: 700;
  line-height: 26px;
  text-align: center;
  color: #2563eb;
  background: #dbeafe;
}

@media (min-width: 768px) {
  .page-login {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 36px 20px;
  }

  .login-shell {
    max-width: 460px;
  }
}
</style>
