<template>
  <div class="login-wrapper">
    <div class="user-card ">
      <UserHeader />
      <UserText :user-text="userText" />
      <UserTabs v-model="activeTab" :tab-list="tabList" />

      <el-form class="user-form" ref="registerFormRef" :model="registerForm" :rules="registerRules">
        <Transition name="form-switch" mode="out-in">
          <el-form-item class="captcha-item" v-if="activeTab === 'email'" key="form-email-item" prop="email">
            <el-input v-model="registerForm.email" placeholder="请输入邮箱" clearable size="large" />
            <el-button type="primary" class="captcha-btn" @click="handleSendCode" :disabled="emailIsCounting">{{
              emailIsCounting ? `${emailCountdown}s后重新获取` : '发送验证码' }}</el-button>
          </el-form-item>

          <el-form-item class="phone-item captcha-item" prop="phone" v-else-if="activeTab === 'phone'"
            key="form-phone-item">
            <el-select v-model="registerForm.countryCode" :teleported="false" value-key="code" placeholder="国家"
              size="large">
              <el-option v-for="item in countryOptions" :key="item.code" :label="item.code" :value="item.code">
                <div class="country-option">
                  <span class="country-name">{{ item.name }}</span>
                  <span class="country-code">{{ item.code }}</span>
                </div>
              </el-option>
            </el-select>
            <el-input v-model="registerForm.phone" placeholder="请输入手机号" clearable size="large" />
            <el-button type="primary" class="captcha-btn" @click="handleSendCode" :disabled="phoneIsCounting">{{
              phoneIsCounting ? `${phoneCountdown}s后重新获取` : '发送验证码' }}</el-button>
          </el-form-item>
        </Transition>

        <UserCaptcha v-model="registerForm.code" />
        <el-form-item label="设置密码(6-12位密码)" label-position="top" prop="password">
          <el-input placeholder="请输入密码" clearable show-password size="large" type="password"
            v-model="registerForm.password" />
        </el-form-item>
        <el-form-item label="邀请链接/邀请码(选填)" label-position="top" prop="inviteCode">
          <el-input placeholder="请输入邀请链接/邀请码" clearable size="large" type="text" v-model="registerForm.inviteCode" />
        </el-form-item>
        <el-form-item prop="agreeAgreement">
          <div style="display: flex;align-items: center; justify-content: flex-start;">
            <el-checkbox v-model="registerForm.agreeAgreement"></el-checkbox>
            <div style="font-size: 13px;display: flex;flex-wrap: wrap;margin-left: 8px;line-height: 17px;">
              我已阅读并同意
              <span class="doc-link" @click="openDoc('服务条款.docx', '服务条款')">《服务条款》</span>、
              <span class="doc-link" @click="openDoc('隐私协议.docx', '隐私协议')">《隐私协议》</span>和
              <span class="doc-link" @click="openDoc('风险提示.docx', '风险提示')">《风险提示》</span>
            </div>
          </div>
        </el-form-item>
        <el-form-item class="form-submit">
          <el-button type="primary" class="form-btn" @click="handleRegister" :loading="buttonLoading">注册</el-button>
        </el-form-item>
        <router-link to="/user/login" class="to-login">已有账号？立即登录</router-link>
      </el-form>
    </div>

    <!-- 协议预览弹窗 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="70%" top="3vh">
      <div class="doc-preview" v-html="docHtml"></div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">关闭</el-button>
          <el-button type="primary" @click="downloadCurrentDoc">下载文档</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import mammoth from 'mammoth'
import { ref, onUnmounted, onMounted } from 'vue'
import termFile from '@/assets/file/服务条款.docx?url'
import privacyFile from '@/assets/file/隐私协议.docx?url'
import riskFile from '@/assets/file/风险提示.docx?url'
defineOptions({
  name: 'Register'
})
// type类型
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
// 组件
import UserHeader from './components/Header.vue'
import UserText from './components/Text.vue'
import UserTabs from './components/Tabs.vue'
import UserCaptcha from './components/Captcha.vue'

//公共方法/store/配置文件
import { useUserStore } from '@/stores/modules/user'
import { md5Encrypt } from '@/utils/crypto'
import { sendCaptcha, initCaptchaState, clearCaptchaTimer } from '@/utils/sendCaptcha'
import { useButtonLoading } from '@/composables/useLoading'

//用户校验规则
import { countryOptions } from '@/views/user/config/mock'
import { passwordRules, emailRules, phoneRules, codeRules } from './config/rules'
import { useRoute } from 'vue-router'

//store实例
const userStore = useUserStore()
const route = useRoute()

// 弹窗相关
const dialogVisible = ref(false)
const dialogTitle = ref('')
const docHtml = ref('')
let currentDocName = ref('')

// 按钮 loading
const { buttonLoading, startButtonLoading, stopButtonLoading } = useButtonLoading()

// UserText 实例
const userText = ref({
  backText: '',
  title: '注册',
  text: '',
})

//tabs 实例
const tabList = ref([
  { label: '邮箱', name: 'email' },
  { label: '手机', name: 'phone' },
])
const activeTab = ref<string>('email')

// 注册表单实例
const registerFormRef = ref<FormInstance>()
const registerForm = ref<any>({
  email: '',
  countryCode: '+86',
  phone: '',
  password: '',
  code: '',
  inviteCode: '',
  agreeAgreement: false,
})
const registerRules = ref<FormRules>({
  email: emailRules().email,
  phone: phoneRules(registerForm.value).phone,
  password: passwordRules(registerForm.value).password,
  code: codeRules().code,
  agreeAgreement: [
    {
      validator: (rule: any, value: any, callback: any) => {
        if (!value) {
          callback(new Error('请勾选同意注册协议'))
        } else {
          callback()
        }
      },
      trigger: 'change',
    },
  ],
})

//初始化验证码倒计时状态（添加页面前缀隔离不同页面的倒计时状态）
const emailCaptchaState = initCaptchaState('email', 60, 'register_email') // 邮箱专属
const phoneCaptchaState = initCaptchaState('phone', 60, 'register_phone') // 手机专属
// 邮箱验证码状态
const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState
// 手机验证码状态
const { isCounting: phoneIsCounting, countdown: phoneCountdown } = phoneCaptchaState

const fileMap: Record<string, string> = {
  '服务条款.docx': termFile,
  '隐私协议.docx': privacyFile,
  '风险提示.docx': riskFile,
}

// 打开并解析docx弹窗预览

async function openDoc(fileName: string, title: string) {
  currentDocName.value = fileName
  dialogTitle.value = title
  dialogVisible.value = true
  docHtml.value = '加载中...'
  const url = fileMap[fileName]
  try {
    const res = await fetch(url)
    const buf = await res.arrayBuffer()
    const ret = await mammoth.convertToHtml({ arrayBuffer: buf })
    docHtml.value = ret.value
  } catch {
    docHtml.value = '加载失败，请下载查看'
  }
}

// 下载当前打开的文档

function downloadCurrentDoc() {
  const url = fileMap[currentDocName.value]
  const a = document.createElement('a')
  a.href = url
  a.download = currentDocName.value
  a.click()
}

//方法

// 定义发送验证码接口
const sendCodeApi = async () => {
  // 发送验证码参数
  const sendParams = {
    email: registerForm.value.email,
    mobile: registerForm.value.countryCode + registerForm.value.phone,
    mobile_area: registerForm.value.countryCode,
    type: 'reg_code',
  }
  return userStore.sendCode(sendParams)
}
//发送验证码
const handleSendCode = async () => {
  if (!registerFormRef.value) return
  try {
    await registerFormRef.value.validateField(activeTab.value)
  } catch (error) {
    console.error('字段校验失败：', error)
    return
  }

  // 确定类型、接收方、对应的倒计时状态和发送函数
  const type: string = activeTab.value === 'phone' ? 'phone' : 'email'
  const receiver =
    type === 'phone'
      ? registerForm.value.countryCode + registerForm.value.phone
      : registerForm.value.email
  const currentCaptchaState = type === 'phone' ? phoneCaptchaState : emailCaptchaState
  const sendFunc = type === 'phone' ? 'sendPhoneCaptcha' : 'sendEmailCaptcha'
  console.log('registerForm.countryCode', registerForm.value.countryCode)
  // 调用封装的发送函数（传正确的函数，而非字符串）
  await sendCaptcha(
    type,
    receiver,
    currentCaptchaState, // 只更新当前类型的倒计时状态
    () => sendCodeApi(), // 传入返回Promise的函数
  )
}

//注册
const handleRegister = async () => {
  if (!registerFormRef.value) return

  // 先检查协议勾选状态
  if (!registerForm.value.agreeAgreement) {
    ElMessage.error('请勾选同意注册协议')
    return
  }

  try {
    // 提交时再次验证（显示错误提示）
    await registerFormRef.value.validate()
    // 开启 loading
    startButtonLoading()
    try {
      // 注册参数
      const registerParams = {
        email: registerForm.value.email,
        mobile_area: registerForm.value.countryCode,
        mobile: registerForm.value.countryCode + registerForm.value.phone,
        reg_type: activeTab.value === 'email' ? 1 : 2,
        invite_code: registerForm.value.inviteCode,
        code: registerForm.value.code,
        password: registerForm.value.password,
      }

      // 注册逻辑
      await userStore.register(registerParams)
    } finally {
      // 关闭 loading
      stopButtonLoading()
    }
  } catch (error) {
    console.error('表单校验失败：', error)
  }
}
// 组件卸载时清除定时器（关键：防止内存泄漏）
onUnmounted(() => {
  clearCaptchaTimer(emailCaptchaState)
  clearCaptchaTimer(phoneCaptchaState)
})

onMounted(() => {
  registerForm.value.inviteCode = route.query.invite_code || ''
})
</script>

<style scoped lang="scss">
.login-wrapper {
  min-height: 100vh;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: radial-gradient(ellipse at center, #f0f7ff 0%, #e8f4fd 40%, #f5f9ff 100%);
}

a {
  text-decoration: none;
  color: var(--el-color-primary);
  margin: 0 4px;
}

.doc-link {
  color: var(--el-color-primary);
  cursor: pointer;
  margin: 0 4px;
}

.user-form {
  .phone-item,
  .captcha-item {
    :deep(.el-form-item__content) {
      flex-wrap: nowrap;
    }

    :deep(.el-select-dropdown__item) {
      padding: 0 16px 0 16px;
    }

    .el-select {
      width: 180px !important;
    }
  }

  .to-login {
    display: flex;
    justify-content: center;
    text-decoration: none;
    color: #409eff;
    margin-top: 24px;
  }
}
</style>
<style lang="scss">
/* 弹窗预览全局样式，不要scoped */
.doc-preview {
  max-height: 65vh;
  overflow-y: auto;
  line-height: 1.8;
  font-size: 15px;
  padding: 10px;
  h1, h2, h3, h4 {
    margin: 16px 0 8px;
  }
  p {
    margin: 8px 0;
  }
  table {
    border-collapse: collapse;
    width: 100%;
    margin: 12px 0;
    td, th {
      border: 1px solid #ccc;
      padding: 6px 10px;
    }
  }
}
</style>