<template>
  <div class="public-auth-page">
    <div class="auth-card">
      <img src="@/assets/images/logo-icon.png" alt="智创未来" class="auth-logo" />
      <h2 class="auth-title">{{ isRegister ? "创建账号" : "登录" }}</h2>
      <p class="auth-subtitle">
        {{ isRegister ? "加入乐绘世界，开启创作之旅" : "欢迎回来，继续你的创作" }}
      </p>

      <a-form ref="formRef" :model="form" :rules="currentRules" layout="vertical" class="auth-form"
        @keyup.enter="submitForm">
        <a-form-item v-if="showNicknameField" name="nickname" label="昵称">
          <a-input v-model:value="form.nickname" :maxlength="15" placeholder="给自己取个名字吧" size="large" />
        </a-form-item>

        <a-form-item v-if="showPhoneField" name="phone" label="手机号">
          <a-input v-model:value="form.phone" placeholder="请输入手机号" size="large" :maxlength="11" />
        </a-form-item>

        <a-form-item v-if="showSmsCodeField" name="smsCode" label="验证码">
          <div style="display: flex; gap: 8px">
            <a-input v-model:value="form.smsCode" placeholder="请输入6位验证码" size="large" :maxlength="6" style="flex: 1" />
            <a-button size="large" :disabled="smsCountdown > 0 || !isPhoneValid" :loading="smsSending"
              @click="handleSendSms" style="min-width: 120px">
              {{ smsCountdown > 0 ? `${smsCountdown}s 后重发` : "获取验证码" }}
            </a-button>
          </div>
        </a-form-item>

        <a-form-item v-if="showUsernameField" name="username" label="账号">
          <a-input v-model:value="form.username" :maxlength="12" placeholder="请输入账号" size="large" />
        </a-form-item>

        <a-form-item v-if="showPasswordField" name="password" label="密码">
          <a-input-password v-model:value="form.password" :maxlength="16" placeholder="请输入密码" size="large" />
        </a-form-item>

        <a-form-item v-if="isRegister" name="confirmPassword" label="确认密码">
          <a-input-password v-model:value="form.confirmPassword" :maxlength="16" placeholder="再次输入密码" size="large" />
        </a-form-item>

        <a-form-item>
          <a-button type="primary" html-type="button" size="large" :loading="loading" block class="auth-btn"
            @click="submitForm">
            {{ isRegister ? "注册并登录" : "登录" }}
          </a-button>
        </a-form-item>
      </a-form>

      <div v-if="!isRegister" class="login-method-switch">
        <a @click="toggleLoginMethod">
          {{ loginMethod === 'password' ? '使用手机号登录' : '使用账号密码登录' }}
        </a>
      </div>

      <div class="auth-switch">
        <template v-if="isRegister">
          已有账号？
          <a @click="switchToLogin">去登录</a>
        </template>
        <template v-else>
          还没有账号？
          <a @click="switchToRegister">立即注册</a>
        </template>
      </div>

      <div class="admin-entry">
        <span>管理端入口：</span>
        <a @click="$router.push('/super/login')">平台超管</a>
        <a-divider type="vertical" />
        <a @click="$router.push('/gdlib/login')">广东省图</a>
        <a-divider type="vertical" />
        <a @click="$router.push('/judge/login')">评委端</a>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onUnmounted } from "vue"
import { useRouter, useRoute } from "vue-router"
import { message } from "ant-design-vue"
import { publicAuthApi } from "@/api/public"
import type { FormInstance } from "ant-design-vue"
import type { Rule } from "ant-design-vue/es/form"

const router = useRouter()
const route = useRoute()
const loading = ref(false)
const isRegister = ref(false)
const loginMethod = ref<'password' | 'sms'>('password')

const isDev = import.meta.env.DEV || import.meta.env.VITE_AUTO_FILL_TEST === 'true'

const form = reactive({
  username: isDev ? "demo" : "",
  password: isDev ? "demo123456" : "",
  confirmPassword: "",
  nickname: "",
  phone: isDev ? "13800138000" : "",
  smsCode: "",
})

// 短信验证码相关
const smsCountdown = ref(0)
const smsSending = ref(false)
let smsTimer: ReturnType<typeof setInterval> | null = null

const formRef = ref<FormInstance>()

const isPhoneValid = computed(() => /^1[3-9]\d{9}$/.test(form.phone.trim()))

// 控制字段显示的 computed
const showNicknameField = computed(() => isRegister.value)
const showPhoneField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'sms'))
const showSmsCodeField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'sms'))
const showUsernameField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'password'))
const showPasswordField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'password'))

// 账号名：仅英文字母与数字
const USERNAME_PATTERN = /^[a-zA-Z0-9]+$/
// 密码：英文字母、数字、ASCII 可打印特殊字符（不含空格）
const PASSWORD_PATTERN = /^[\x21-\x7E]+$/

// 基础校验规则（与后端 PublicRegisterDto / PublicLoginDto 一致）
const baseRules: Record<string, Rule[]> = {
  username: [
    { required: true, message: "请输入账号名", trigger: "blur" },
    { min: 4, message: "账号名为4-12个字符", trigger: "blur" },
    { max: 12, message: "账号名为4-12个字符", trigger: "blur" },
    {
      pattern: USERNAME_PATTERN,
      message: "账号名只能包含英文字母与数字",
      trigger: "blur",
    },
  ],
  password: [
    { required: true, message: "请输入密码", trigger: "blur" },
    { min: 6, message: "密码为6-16个字符", trigger: "blur" },
    { max: 16, message: "密码为6-16个字符", trigger: "blur" },
    {
      pattern: PASSWORD_PATTERN,
      message: "密码只能包含英文字母、数字与特殊字符",
      trigger: "blur",
    },
  ],
  confirmPassword: [
    { required: true, message: "请确认密码", trigger: "blur" },
    {
      validator: (_: any, value: string) => {
        if (value !== form.password) {
          return Promise.reject("两次输入的密码不一致")
        }
        return Promise.resolve()
      },
      trigger: "blur",
    },
  ],
  nickname: [
    { required: true, message: "请输入昵称", trigger: "blur" },
    { min: 2, message: "昵称为2-20个字符", trigger: "blur" },
    { max: 20, message: "昵称为2-20个字符", trigger: "blur" },
  ],
  phone: [
    { required: true, message: "请输入手机号", trigger: "blur" },
    { pattern: /^1[3-9]\d{9}$/, message: "手机号格式不正确", trigger: "blur" },
  ],
  smsCode: [
    { required: true, message: "请输入验证码", trigger: "blur" },
    { len: 6, message: "验证码为6位数字", trigger: "blur" },
    { pattern: /^\d{6}$/, message: "验证码只能为数字", trigger: "blur" },
  ],
}

// 根据当前模式动态生成校验规则
const currentRules = computed(() => {
  const rules: Record<string, Rule[]> = {}
  if (isRegister.value) {
    // 注册模式：昵称、手机号、验证码、用户名、密码、确认密码
    rules.nickname = baseRules.nickname
    rules.phone = baseRules.phone
    rules.smsCode = baseRules.smsCode
    rules.username = baseRules.username
    rules.password = baseRules.password
    rules.confirmPassword = baseRules.confirmPassword
  } else if (loginMethod.value === 'password') {
    // 密码登录模式：用户名、密码
    rules.username = baseRules.username
    rules.password = baseRules.password
  } else {
    // 验证码登录模式：手机号、验证码
    rules.phone = baseRules.phone
    rules.smsCode = baseRules.smsCode
  }
  return rules
})

const handleSendSms = async () => {
  form.phone = form.phone.trim()
  if (!isPhoneValid.value || smsCountdown.value > 0) return
  smsSending.value = true
  try {
    await publicAuthApi.sendSmsCode(form.phone)
    message.success("验证码已发送")
    // 开始 60 秒倒计时
    smsCountdown.value = 60
    smsTimer = setInterval(() => {
      smsCountdown.value--
      if (smsCountdown.value <= 0) {
        if (smsTimer) clearInterval(smsTimer)
        smsTimer = null
      }
    }, 1000)
  } catch (error: any) {
    const msg = error?.response?.data?.message || "验证码发送失败"
    message.error(msg)
  } finally {
    smsSending.value = false
  }
}

// 组件销毁时清理定时器
onUnmounted(() => {
  if (smsTimer) clearInterval(smsTimer)
})

const toggleLoginMethod = () => {
  loginMethod.value = loginMethod.value === 'password' ? 'sms' : 'password'
}

const switchToRegister = () => {
  isRegister.value = true
  loginMethod.value = 'password'
}

const switchToLogin = () => {
  isRegister.value = false
  loginMethod.value = 'password'
}

/** 校验前去除各字段前后空格并写回表单，再触发校验 */
function trimFormFields() {
  const t = (v: string) => (typeof v === "string" ? v.trim() : v)
  form.nickname = t(form.nickname)
  form.phone = t(form.phone)
  form.smsCode = t(form.smsCode)
  form.username = t(form.username)
  form.password = t(form.password)
  form.confirmPassword = t(form.confirmPassword)
}

function submitForm() {
  trimFormFields()
  formRef.value
    ?.validate()
    .then(() => handleSubmit())
    .catch(() => { })
}

const handleSubmit = async () => {
  loading.value = true
  try {
    let result
    if (isRegister.value) {
      result = await publicAuthApi.register({
        username: form.username,
        password: form.password,
        nickname: form.nickname,
        phone: form.phone,
        smsCode: form.smsCode,
      })
      message.success("注册成功")
    } else if (loginMethod.value === 'sms') {
      result = await publicAuthApi.loginBySms({
        phone: form.phone,
        smsCode: form.smsCode,
      })
      message.success("登录成功")
    } else {
      result = await publicAuthApi.login({
        username: form.username,
        password: form.password,
      })
      message.success("登录成功")
    }

    // 保存 token 和用户信息
    if (result?.token && result?.user) {
      localStorage.setItem("public_token", result.token)
      localStorage.setItem("public_user", JSON.stringify(result.user))
    } else {
      console.error("注册/登录返回数据异常：", result)
      message.error(isRegister.value ? "注册返回数据异常" : "登录返回数据异常")
      return
    }

    // 跳转
    const redirect = (route.query.redirect as string) || "/p/activities"
    router.push(redirect)
  } catch (error: any) {
    const msg =
      error?.response?.data?.message ||
      (isRegister.value ? "注册失败" : "登录失败")
    message.error(msg)
  } finally {
    loading.value = false
  }
}
</script>

<style scoped lang="scss">
$primary: #6366f1;

.public-auth-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #eef2ff 0%, #fdf2f8 50%, #ecfdf5 100%);
  padding: 20px;
}

.auth-card {
  width: 100%;
  max-width: 400px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(20px);
  border-radius: 24px;
  padding: 40px 32px;
  box-shadow: 0 8px 32px rgba(99, 102, 241, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.5);
  text-align: center;
}

.auth-logo {
  width: 64px;
  height: 64px;
  object-fit: contain;
  margin-bottom: 16px;
  filter: drop-shadow(0 4px 8px rgba(99, 102, 241, 0.15));
}

.auth-title {
  font-size: 22px;
  font-weight: 800;
  color: #1e1b4b;
  margin: 0 0 6px;
}

.auth-subtitle {
  font-size: 14px;
  color: #9ca3af;
  margin: 0 0 28px;
}

.auth-form {
  text-align: left;

  :deep(.ant-input-affix-wrapper) {
    border-radius: 12px !important;
    border-color: #e5e1f5 !important;
    height: 44px;
    padding: 4px 11px;

    &:focus,
    &:hover,
    &.ant-input-affix-wrapper-focused {
      border-color: $primary !important;
    }

    .ant-input {
      height: auto;
    }
  }

  :deep(.ant-input:not(.ant-input-affix-wrapper .ant-input)) {
    border-radius: 12px !important;
    border-color: #e5e1f5 !important;
    height: 44px;

    &:focus,
    &:hover {
      border-color: $primary !important;
    }
  }

  :deep(.ant-form-item-label > label) {
    font-weight: 600;
    font-size: 13px;
    color: #374151;
  }
}

.auth-btn {
  height: 46px !important;
  border-radius: 12px !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  background: linear-gradient(135deg, $primary 0%, #ec4899 100%) !important;
  border: none !important;
  box-shadow: 0 4px 16px rgba(99, 102, 241, 0.3);
  letter-spacing: 1px;

  &:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4);
  }
}

.login-method-switch {
  margin-top: 16px;
  font-size: 13px;
  color: #9ca3af;

  a {
    color: $primary;
    font-weight: 600;
    cursor: pointer;

    &:hover {
      color: #ec4899;
    }
  }
}

.auth-switch {
  margin-top: 12px;
  font-size: 13px;
  color: #9ca3af;

  a {
    color: $primary;
    font-weight: 600;
    cursor: pointer;

    &:hover {
      color: #ec4899;
    }
  }
}

.admin-entry {
  margin-top: 16px;
  text-align: center;
  font-size: 12px;
  color: #d1d5db;

  a {
    color: #9ca3af;
    cursor: pointer;

    &:hover {
      color: $primary;
    }
  }
}

@media (max-width: 480px) {
  .auth-card {
    padding: 32px 24px;
    border-radius: 20px;
  }
}
</style>
