<template>
  <form @submit.prevent="handleLogin" class="flex flex-col gap-6 text-base text-black md:text-2xl">
    <div class="rounded-[20px] bg-[#78788029] px-4">
      <div class="relative">
        <Input
          v-model.trim="email"
          type="text"
          name="user_email_identity"
          autocomplete="new-password"
          placeholder="Email"
          class="h-[50px] border-none bg-transparent text-base focus-visible:ring-0 md:text-2xl"
          @focus="isFocused = true"
          @blur="onBlur"
          @keydown="handleKeyDown"
        />
        <transition name="fade">
          <div
            v-if="isFocused && suggestList.length > 0"
            class="absolute top-[55px] left-0 z-[100] w-full rounded-xl border border-white/20 bg-white/95 p-1 shadow-2xl backdrop-blur-xl dark:bg-black/90"
          >
            <div
              v-for="(item, index) in suggestList"
              :key="item.full"
              @mousedown="selectSuggest(item.full)"
              :class="[
                'flex cursor-pointer items-center rounded-lg px-3 py-2 text-sm transition-colors md:text-xl',
                activeIndex === index ? 'bg-[#A8FF53]/10' : '',
              ]"
            >
              <span class="font-medium text-black/80">{{ prefix }}</span>

              <span class="font-medium text-black">{{ item.userInputPart }}</span>

              <span class="text-black opacity-30">{{ item.suggestPart }}</span>
            </div>
          </div>
        </transition>
        <div class="absolute bottom-0 left-0 h-[1px] w-full bg-gray-400/30"></div>
      </div>

      <div class="relative flex items-center">
        <div class="flex-1">
          <Input
            v-model.trim="code"
            type="text"
            inputmode="numeric"
            name="code"
            autocomplete="one-time-code"
            placeholder="验证码"
            class="h-[50px] border-none bg-transparent text-base focus-visible:ring-0 md:text-2xl"
          />
        </div>
        <Button
          @click="handleGetCode"
          :disabled="countdown > 0 || isSendingCode"
          class="relative h-10 min-w-[100px] cursor-pointer overflow-hidden rounded-full bg-[#4B94E6] px-[32px] text-base font-bold text-white hover:bg-[#4B94E6]/90 md:min-w-[130px] md:px-[45px] md:text-[18px]"
        >
          <div class="flex items-center justify-center">
            <Loader2 v-if="isSendingCode" class="absolute left-4 h-4 w-4 animate-spin md:left-8" />

            <span :class="{ 'ml-4': isSendingCode }">
              {{ isSendingCode ? '发送中' : countdown > 0 ? `${countdown}s` : '获取' }}
            </span>
          </div>
        </Button>
      </div>
    </div>

    <div class="flex gap-4 pt-2">
      <Button
        type="button"
        variant="secondary"
        @click="emit('close')"
        class="h-[48px] flex-1 cursor-pointer rounded-[25px] bg-[#D1D1D1] text-lg font-medium text-[#757575] hover:bg-[#C1C1C1]"
      >
        取消
      </Button>
      <Button
        type="submit"
        :disabled="isLoggingIn"
        class="relative h-[48px] flex-1 cursor-pointer overflow-hidden rounded-[25px] bg-[#A8FF53] text-lg font-medium text-black hover:bg-[#96E64A]"
      >
        <div class="flex items-center justify-center">
          <Loader2 v-if="isLoggingIn" class="absolute left-4 h-5 w-5 animate-spin md:left-8" />
          <span :class="{ 'ml-2': isLoggingIn }"> 登录/注册 </span>
        </div>
      </Button>
    </div>
    <CodeSentTip ref="CodeSentTipRef" />
  </form>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { toast } from 'vue-sonner'
import CodeSentTip from '@/pages/Home/components/CodeSentTip.vue'
import request from '@/utils/request'
import { useRouter } from 'vue-router'
import { Loader2 } from 'lucide-vue-next'

const CodeSentTipRef = ref<InstanceType<typeof CodeSentTip> | null>(null)
const email = ref('')
const code = ref('')
const countdown = ref(0)
const isFocused = ref(false)
const commonSuffixes = ['@gmail.com', '@outlook.com', '@qq.com', '@163.com']
const activeIndex = ref(-1) // 记录当前键盘选中的索引
const isSendingCode = ref(false) // 新增 loading 状态

// 1. 逻辑：提取 @ 前的字符
const prefix = computed(() => {
  const atIndex = email.value.indexOf('@')
  return atIndex > -1 ? email.value.slice(0, atIndex) : email.value
})

// 输入变化时重置索引
watch(email, () => {
  activeIndex.value = -1
})
// 键盘控制逻辑
const handleKeyDown = (e: KeyboardEvent) => {
  if (!suggestList.value.length) return

  if (e.key === 'ArrowDown') {
    e.preventDefault()
    activeIndex.value = (activeIndex.value + 1) % suggestList.value.length
  } else if (e.key === 'ArrowUp') {
    e.preventDefault()
    activeIndex.value =
      (activeIndex.value - 1 + suggestList.value.length) % suggestList.value.length
  } else if (e.key === 'Enter' && activeIndex.value !== -1) {
    e.preventDefault()
    // 修复之前的 [object Object] 问题，确保传入的是 .full
    selectSuggest(suggestList.value[activeIndex.value].full)
  } else if (e.key === 'Tab' && activeIndex.value !== -1) {
    // 💡 新增：按下 Tab 键时也自动补全
    e.preventDefault()
    selectSuggest(suggestList.value[activeIndex.value].full)
  }
}

// 2. 逻辑：生成建议列表
const suggestList = computed(() => {
  const val = email.value.trim()
  if (!val || val.length < 1) return []

  const atIndex = val.indexOf('@')
  // 用户目前输入的后缀部分（例如输入了 "abc@gm"，则 domainPart 为 "@gm"）
  const domainPart = atIndex > -1 ? val.slice(atIndex) : ''

  // 过滤匹配的后缀
  const matches = commonSuffixes.filter((s) => s.startsWith(domainPart) && s !== domainPart)

  return matches.map((full) => {
    return {
      full: full, // 完整后缀，用于点击填入
      userInputPart: domainPart, // 用户已经输入的后缀部分（标色）
      suggestPart: full.replace(domainPart, ''), // 还没输入的推荐部分（置灰）
    }
  })
})

// 4. 处理选中
const selectSuggest = (fullSuffix: string) => {
  email.value = prefix.value + fullSuffix
  isFocused.value = false
}

const onBlur = () => {
  // 必须延迟，否则点击列表时会先触发 blur 导致列表消失无法选中
  setTimeout(() => {
    isFocused.value = false
    activeIndex.value = -1 // 重置索引
  }, 200)
}

// 3. 校验逻辑
const validateEmail = (str: string) => {
  return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(str)
}
const emit = defineEmits(['close'])
const handleGetCode = async () => {
  if (!email.value) {
    toast('请输入邮箱')
    return
  }

  if (!validateEmail(email.value)) {
    return toast.error('邮箱格式无效，请检查')
  }

  isSendingCode.value = true // [开始加载]

  try {
    // 1. 检查用户是否存在
    const { exist } = await request.get<{ exist: boolean }>('/api/v1/auth/check', {
      email: email.value,
    })

    // 2. 发送验证码
    await request.post('/api/v1/common/send_code', {
      email: email.value,
      type: exist ? 2 : 1, // 1=登录, 2=注册
    })

    // 3. 成功后的后续处理
    CodeSentTipRef.value?.show()
    countdown.value = 60
    const timer = setInterval(() => {
      countdown.value--
      if (countdown.value <= 0) clearInterval(timer)
    }, 1000)
  } catch (error: any) {
    console.error('发送验证码失败:', error)
    // 错误处理已经在 request 拦截器或此处 toast 过了
  } finally {
    isSendingCode.value = false // [结束加载]
  }
}
const router = useRouter()
const isLoggingIn = ref(false)

const handleLogin = () => {
  if (!code.value) {
    toast('请输入验证码')
    return
  }
  if (!validateEmail(email.value)) {
    return toast.error('邮箱格式无效，请检查')
  }

  isLoggingIn.value = true
  request
    .post<any, { token: string }>('/api/v1/auth/login/email', {
      email: email.value,
      code: code.value,
    })
    .then((res) => {
      localStorage.setItem('Authorization', res.token)
      localStorage.setItem('UserEmail', email.value)
      router.push({ path: '/user-center' })
    })
    .catch((error) => {
      console.error('登录失败', error)
    })
    .finally(() => {
      isLoggingIn.value = false
    })
}
</script>

<style scoped>
/* 移除 Shadcn Input 的默认边框阴影，保持纯净感 */
input:focus {
  outline: none;
}
</style>
