<template>
  <view class="page" :style="cssVars">
    <!-- Header：仅保留左侧Logo -->
    <view class="header">
      <view class="header-left">
        <image :src="logoUrl" mode="aspectFit" class="logo" />
      </view>
    </view>

    <!-- Main -->
    <view class="main">
      <view class="card">
        <!-- Left：扫码区（>=768显示） -->
        <view class="left">
          <text class="left-title">APP 扫码登录</text>

          <view class="left-hint">
            <text class="hint-text">打开 APP 扫一扫</text>
            <text class="hint-link" @click="handleTutorial">查看教程</text>
          </view>

          <view class="qr-wrap">
            <view class="qr">
              <view class="qr-placeholder">
                <text class="qr-text">二维码占位</text>
                <text class="qr-sub">220×220</text>
              </view>
            </view>
          </view>
        </view>

        <!-- Divider -->
        <view class="divider"></view>

        <!-- Right：表单区 -->
        <view class="right">
          <view class="right-inner">
            <!-- Tabs -->
            <view class="tabs">
              <view class="tab" :class="{ active: loginType === 0 }" @click="loginType = 0">
                <text class="tab-text">密码登录</text>
                <view v-if="loginType === 0" class="tab-line"></view>
              </view>

              <view class="tab" :class="{ active: loginType === 1 }" @click="loginType = 1">
                <text class="tab-text">短信登录</text>
                <view v-if="loginType === 1" class="tab-line"></view>
              </view>
            </view>

            <!-- Form -->
            <view class="form">
              <template v-if="loginType === 0">
                <view class="field">
                  <input
                    class="input"
                    type="text"
                    placeholder="账号名/手机号/邮箱"
                    v-model="account"
                    autocomplete="off"
                  />
                </view>
                <view class="field password-field">
                  <input
                    class="input"
                    :type="isPasswordVisible ? 'text' : 'password'"
                    placeholder="密码"
                    v-model="password"
                    autocomplete="new-password"
                  />
                  <view class="eye-btn" @click="isPasswordVisible = !isPasswordVisible">
                    <!-- 睁眼(猴子双手打开)表示可见, 闭眼(猴子捂眼)表示不可见 -->
                    <text class="eye-icon">{{ isPasswordVisible ? '🙉' : '🙈' }}</text>
                  </view>
                </view>
              </template>

              <template v-else>
                <view class="field">
                  <input
                    class="input"
                    type="text"
                    placeholder="输入手机号码"
                    maxlength="11"
                    v-model="account"
                    autocomplete="off"
                  />
                </view>

                <view class="field code-row">
                  <input
                    class="input code-input"
                    type="text"
                    placeholder="填写验证码"
                    maxlength="6"
                    v-model="captcha"
                  />
                  <view class="code-btn" :class="codeDisabled ? 'disabled' : ''" @click="getCode">
                    <text class="code-text">{{ codeText }}</text>
                  </view>
                </view>
              </template>

              <!-- Button -->
              <view class="btn" :class="{ disabled: isLoading }" @click="handleLogin">
                <text class="btn-text">登录</text>
              </view>

              <!-- Actions：一行横排 -->
              <view class="actions">
                <view class="action-item" @click="handleWechatLogin">
                  <view class="dot wechat"></view>
                  <text class="action-text">微信登录</text>
                </view>

                <text class="sep">|</text>

                <view class="action-item" @click="handleQQLogin">
                  <view class="dot qq"></view>
                  <text class="action-text">QQ登录</text>
                </view>

                <text class="sep">|</text>

                <text class="action-link" @click="handleForgotPassword">忘记密码</text>

                <text class="sep">|</text>

                <text class="action-link" @click="navigateToRegister">立即注册</text>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>

    <!-- Footer -->
    <view class="footer">
      <text class="footer-text">Copyright ©2024 Mall. All Rights Reserved</text>
    </view>
  </view>
</template>

<script setup lang="uts">
import { ref, onMounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import supa from '@/components/supadb/aksupainstance.uts'
import { IS_TEST_MODE, PUSH_SERVER_URL } from '@/ak/config.uts'
import { getCurrentUser, logout, setIsLoggedIn, setUserProfile } from '@/utils/store.uts'
import { checkMerchantAccount, clearAuth, goMerchantHome, isMerchantRole, requireMerchantAuth, setMerchantInfo } from '@/utils/merchantAuth.uts'
import { clearDeliveryAuth, goDeliveryHome, requireDeliveryAuth, saveDeliverySession } from '@/utils/deliveryAuth.uts'
import { loginDelivery } from '@/services/deliveryService.uts'
import type { UserProfile } from '@/types/mall-types.uts'
import { AkReq } from '@/uni_modules/ak-req/index.uts'

const cssVars = {
  '--bg': '#f5f6f8',
  '--card': '#ffffff',
  '--brand': '#e1251b',
  '--text': '#333333',
  '--muted': '#666666',
  '--muted2': '#999999',
  '--border': '#eeeeee',
  '--inputbg': '#f6f7f9',
  '--shadow': '0 2px 12px rgba(0,0,0,0.06)'
}

const logoUrl = ref<string>('/static/logo.png')

const loginType = ref<number>(0)

// ─────────────────────────────────────────────
// 默认账号密码（唯一来源，修改只改这里）
// 必须在 account/password ref 之前声明，否则 ref 初始化时无法引用
// ─────────────────────────────────────────────
// const TEST_ACCOUNT = 'test@mall.com'   // ← 旧账号（已停用）
// const TEST_PASSWORD = 'Hf2152111'      // ← 旧密码（已停用）
const TEST_ACCOUNT = 'test19@163.com'
const TEST_PASSWORD = 'huang123456'

// ✅ account/password 直接以常量作初始值，上线/刷新立即生效，不再依赖 onMounted 延迟赋值
const account = ref<string>('')
const password = ref<string>('')
const captcha = ref<string>('')
const isPasswordVisible = ref<boolean>(false)

const isLoading = ref<boolean>(false)
const redirectPath = ref<string>('')
const loginMode = ref<string>('consumer')

const getOptionText = (opts: UTSJSONObject, key: string): string => {
  try {
    const value = opts.getString(key)
    if (value != null && value !== '') {
      return value
    }
  } catch (e) {}

  try {
    const rawValue = opts[key]
    if (rawValue != null) {
      return '' + rawValue
    }
  } catch (e) {}

  return ''
}

const isMerchantMode = (): boolean => {
  return loginMode.value === 'merchant'
}

const isDeliveryMode = (): boolean => {
  return loginMode.value === 'delivery'
}

const goTargetHome = (): void => {
  if (isDeliveryMode()) {
    goDeliveryHome()
  } else if (isMerchantMode()) {
    goMerchantHome()
  } else {
    goConsumerHome()
  }
}

onLoad((opts) => {
  if (opts != null) {
    const optsObj = opts as UTSJSONObject
    redirectPath.value = getOptionText(optsObj, 'redirect')
    const parsedMode = getOptionText(optsObj, 'mode')
    if (parsedMode === 'merchant') {
      loginMode.value = 'merchant'
      uni.setNavigationBarTitle({ title: '商家登录' })
    } else if (parsedMode === 'delivery') {
      loginMode.value = 'delivery'
      uni.setNavigationBarTitle({ title: '服务人员登录' })
    } else {
      loginMode.value = 'consumer'
      uni.setNavigationBarTitle({ title: '登录' })
    }
  }
})

type ParseRoleInput = UTSJSONObject | Array<UTSJSONObject> | string | null

const checkUserAccess = async (uid: string, rawEmail: string): Promise<UTSJSONObject | null> => {
  const email = rawEmail.trim().toLowerCase()

  const parseRoleData = (dataArray: ParseRoleInput): UTSJSONObject | null => {
    if (Array.isArray(dataArray)) {
      const arr = dataArray as Array<UTSJSONObject>
      if (arr.length > 0) {
        const obj = arr[0]
        const role = obj.getString('role') ?? ''
        const id = obj.getString('id') ?? ''
        const allowed = isMerchantMode() ? (role === 'merchant') : (role === 'consumer' || role === 'customer')
        if (allowed && id !== '') {
          return { id, role } as UTSJSONObject
        }
      }
    }
    return null
  }

  try {
    let res = await supa.from('ak_users').select('id, role').eq('auth_id', uid).execute()
    let parsed = parseRoleData(res.data)
    if (parsed != null) return parsed

    res = await supa.from('ak_users').select('id, role').eq('id', uid).execute()
    parsed = parseRoleData(res.data)
    if (parsed != null) return parsed

    if (email !== '') {
      res = await supa.from('ak_users').select('id, role').eq('email', email).execute()
      parsed = parseRoleData(res.data)
      if (parsed != null) return parsed
    }

    throw new Error('NOT_REGISTERED')
  } catch (e) {
    if (e instanceof Error && e.message === 'NOT_REGISTERED') {
      if (isMerchantMode()) {
        throw new Error('该账户不是商家账号，或数据库中不存在该账户')
      }
      throw new Error('该账户不是消费者，或数据库中不存在该账户')
    }
    if (isMerchantMode()) {
      throw new Error('商家身份校验失败，请联系管理员检查用户数据')
    }
    throw new Error('消费者身份校验失败，请联系管理员检查用户数据')
  }
}

const codeDisabled = ref<boolean>(false)
const codeText = ref<string>('获取验证码')
const codeTimer = ref<number>(0)
const codeCountdown = ref<number>(0)

const goConsumerHome = (): void => {
  uni.reLaunch({ url: '/pages/main/index' })
}

const isTabBarPage = (url: string): boolean => {
  return url === '/pages/main/index'
    || url === '/pages/main/category'
    || url === '/pages/main/messages'
    || url === '/pages/main/cart'
    || url === '/pages/main/profile'
    || url === '/pages/mall/delivery/home/index'
    || url === '/pages/mall/delivery/orders/index'
    || url === '/pages/mall/delivery/messages/index'
    || url === '/pages/mall/delivery/profile/index'
}

const navigateToRedirect = (redirect: string): void => {
  const target = decodeURIComponent(redirect) ?? ''
  if (target === '') {
    goTargetHome()
    return
  }

  if (isTabBarPage(target)) {
    uni.switchTab({ url: target })
    return
  }

  uni.redirectTo({ url: target })
}

const redirectAfterMount = (redirect: string): void => {
  setTimeout(() => {
    if (redirect !== '') {
      navigateToRedirect(redirect)
    } else {
      goTargetHome()
    }
  }, 80)
}

const checkLoginStatus = async (): Promise<void> => {
  try {
    const sessionInfo = supa.getSession()
    const storedId = uni.getStorageSync('user_id')
    const hasSession = sessionInfo != null && sessionInfo.user != null
    const hasStorage = storedId != null && (storedId as string) !== ''
    if (isDeliveryMode()) {
      const authResult = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
      if (!authResult.ok) {
        return
      }
      const redirect = redirectPath.value
      redirectAfterMount(redirect)
      return
    }
    if (hasSession && hasStorage) {
      if (isMerchantMode()) {
        const authResult = await requireMerchantAuth({ redirectOnFail: false, toastOnFail: false })
        if (!authResult.ok) {
          return
        }
      }
      const redirect = redirectPath.value
      console.log('检测到已有会话, 执行重定向...')
      redirectAfterMount(redirect)
    }
  } catch (e) {
    console.error('检查登录状态失败:', e)
  }
}

onMounted(() => {
  // ── 调试日志（开发阶段保留，上线前可删除）──
  console.log('[Login] ▶ onMounted 开始')
  console.log('[Login] 📝 form 初始值:', {
    account: account.value,
    password: account.value === TEST_ACCOUNT ? '(TEST_PASSWORD 默认)' : '(ref 已被其他逻辑覆盖)'
  })

  // 检查是否存在旧版本 loginn.uvue 遗留的 rememberEmail 缓存
  try {
    const storedEmail = uni.getStorageSync('rememberEmail') as string | null
    console.log('[Login] 📦 读取 storage[rememberEmail]:', storedEmail ?? '(无)')
    if (storedEmail != null && storedEmail.trim() !== '') {
      // 如果存在之前的记住密码缓存，创建账号使用缓存，密码空留用户手动输入
      console.log('[Login] ℹ️ 发现 rememberEmail 缓存，使用缓存账号:', storedEmail)
      account.value = storedEmail
      password.value = '' // 密码不缓存，须用户手动输入
    } else {
      console.log('[Login] ℹ️ 无缓存，使用默认账号密码（已由 ref 初始化）')
      // account 和 password 已在 ref 声明时直接用 TEST_ACCOUNT/TEST_PASSWORD 初始化，无需重复赋值
    }
  } catch (e) {
    console.error('[Login] ⚠️ 读取 rememberEmail 失败（已忽略）:', e)
  }

  console.log('[Login] 📝 onMounted 完成，最终 form 値:', {
    account: account.value,
    isDefault: account.value === TEST_ACCOUNT
  })

  if (isDeliveryMode()) {
    account.value = ''
    password.value = ''
  } else if (isMerchantMode()) {
    account.value = TEST_ACCOUNT
    password.value = TEST_PASSWORD
  }

  checkLoginStatus()
})

const validateAccount = (): boolean => {
  if (account.value.trim() === '') {
    uni.showToast({ title: '请填写账号', icon: 'none' })
    return false
  }
  if (loginType.value === 1) {
    if (!/^1[3-9]\d{9}$/.test(account.value)) {
      uni.showToast({ title: '请输入正确的手机号码', icon: 'none' })
      return false
    }
  }
  return true
}

const validatePassword = (): boolean => {
  if (password.value.trim() === '') {
    uni.showToast({ title: '请填写密码', icon: 'none' })
    return false
  }
  if (password.value.length < 6) {
    uni.showToast({ title: '密码长度不能少于6位', icon: 'none' })
    return false
  }
  return true
}

const validateCaptcha = (): boolean => {
  if (captcha.value.trim() === '') {
    uni.showToast({ title: '请填写验证码', icon: 'none' })
    return false
  }
  if (!/^\d{6}$/.test(captcha.value)) {
    uni.showToast({ title: '请输入正确的验证码', icon: 'none' })
    return false
  }
  return true
}

const getCode = async () => {
  if (codeDisabled.value) return
  if (!validateAccount()) return

  uni.showToast({ title: '验证码已发送', icon: 'success' })

  codeDisabled.value = true
  codeCountdown.value = 60
  codeText.value = `${codeCountdown.value}秒后重试`

  codeTimer.value = setInterval(() => {
    codeCountdown.value--
    if (codeCountdown.value > 0) {
      codeText.value = `${codeCountdown.value}秒后重试`
    } else {
      codeDisabled.value = false
      codeText.value = '获取验证码'
      if (codeTimer.value != 0) {
        clearInterval(codeTimer.value)
        codeTimer.value = 0
      }
    }
  }, 1000) as number
}

const handleLogin = async () => {
  if (!validateAccount()) return

  if (isDeliveryMode()) {
    if (loginType.value !== 0) {
      uni.showToast({ title: '服务人员端暂不支持短信登录', icon: 'none' })
      return
    }
    if (!validatePassword()) return
    if (!account.value.includes('@')) {
      uni.showToast({ title: '请使用真实邮箱账号登录', icon: 'none' })
      return
    }

    isLoading.value = true
    try {
      clearAuth()
      clearDeliveryAuth()
      const result = await loginDelivery({ account: account.value.trim(), password: password.value.trim() })
      saveDeliverySession(result.token, result.userInfo, result.deliveryInfo)
      const authResult = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
      if (!authResult.ok) {
        clearDeliveryAuth()
        throw new Error(authResult.message != '' ? authResult.message : '服务人员登录失败')
      }
      uni.$emit('authChanged', { loggedIn: true })
      uni.showToast({ title: '登录成功', icon: 'success' })
      setTimeout(() => {
        const redirect = redirectPath.value
        if (redirect !== '') {
          navigateToRedirect(redirect)
        } else {
          goTargetHome()
        }
      }, 300)
    } catch (err) {
      let msg = '登录失败，请重试'
      try {
        const e = err as Error
        if (e.message != null && e.message.trim() !== '') msg = e.message
      } catch (e2) {}
      uni.showToast({ title: msg, icon: 'none' })
    } finally {
      isLoading.value = false
    }
    return
  }

  // 特殊账号处理：仅在测试模式下保留直登逻辑，生产环境强制校验角色
  if (!isMerchantMode() && IS_TEST_MODE && account.value === 'admin' && password.value === 'admin') {
    setIsLoggedIn(true)
    const adminProfile = {
      id: 'admin',
      username: 'Admin',
      email: 'admin@mall.com',
      gender: 'unknown',
      birthday: '',
      height_cm: 0,
      weight_kg: 0,
      bio: 'Administrator',
      avatar_url: '/static/logo.png',
      preferred_language: 'zh-CN',
      role: isMerchantMode() ? 'admin' : 'consumer',
      school_id: '',
      grade_id: '',
      class_id: ''
    } as UserProfile
    setUserProfile(adminProfile)
    // uni.setStorageSync('merchant_id', 'admin') // mock removed
    
    uni.$emit('authChanged', { loggedIn: true })
    uni.showToast({ title: '管理员登录成功', icon: 'success' })
    setTimeout(() => {
      goTargetHome()
    }, 500)
    return
  }

  if (loginType.value === 0) {
    if (!validatePassword()) return
  } else {
    if (!validateCaptcha()) return
  }

  isLoading.value = true
  try {
    clearAuth()

    if (loginType.value === 0) {
      const isEmail = account.value.includes('@')
      if (isEmail) {
        // 1) 调用 Supabase Auth 登录
        const result = await supa.signIn(account.value.trim(), password.value)
        console.log('signIn result:', result)
        
        // 检查登录是否失败
        if (result.user == null) {
          const rawData = result.raw as UTSJSONObject
          const errorMsg = rawData?.getString('msg') ?? ''
          const errorCode = rawData?.getString('error_code') ?? ''
          
          if (errorMsg.includes('email') && errorMsg.includes('confirm') || 
              errorCode === 'email_not_confirmed' ||
              errorMsg.includes('邮箱') && errorMsg.includes('确认')) {
            throw new Error('邮箱未确认，请先检查邮箱并点击确认链接')
          } else if (errorMsg.includes('Invalid login credentials') || 
                     errorCode === 'invalid_credentials' ||
					 errorMsg.includes('Invalid credentials') ||
                     errorMsg.includes('credentials') ||
                     errorMsg.includes('invalid')) {
            throw new Error('用户名或密码错误')
          } else {
            throw new Error(errorMsg != '' ? errorMsg : '登录失败，请重试')
          }
        }

		// 2) 按当前登录模式校验消费者或商家身份
		const sessionUser = result.user
		let sessionUid = sessionUser?.getString('id') ?? ''
		
		const accessData = await checkUserAccess(sessionUid, account.value)
                if (accessData == null) {
                        await supa.signOut()
					clearAuth()
			throw new Error(isMerchantMode() ? '该账户无商家端权限' : '该账户无消费者权限')
                }

                if (!isMerchantMode()) {
      uni.removeStorageSync('merchant_id')
      uni.removeStorageSync('merchant_info')
    }
      } else {
        uni.showToast({ title: '手机号密码登录功能开发中', icon: 'none' })
        return
      }
    } else {
      uni.showToast({ title: '手机验证码登录功能开发中', icon: 'none' })
      return
    }

    // 更新 store 中的用户资料
    let profile: UserProfile | null = null
    try {
      profile = await getCurrentUser()
      console.log('fetch profile success:', profile)
    } catch (e) {
      console.error('获取用户信息失败（忽略）:', e)
    }

    if (isMerchantMode()) {
      if (profile == null || !isMerchantRole(profile)) {
        clearAuth()
        throw new Error('当前账号不是商家账号')
      }

      const merchantInfo = await checkMerchantAccount(profile)
      if (merchantInfo == null) {
        clearAuth()
        throw new Error('当前账号未绑定商家信息')
      }

      if (merchantInfo.status === 0) {
        clearAuth()
        throw new Error('当前商家信息待审核')
      }

      if (merchantInfo.status != null && merchantInfo.status !== 1) {
        clearAuth()
        throw new Error('当前商家状态异常，暂不可登录')
      }

      setMerchantInfo(merchantInfo)
    }

    // 已移除对 shared storage user_id 的依赖
    const currentSession = supa.getSession()

    uni.$emit('authChanged', { loggedIn: true })
    uni.showToast({ title: '登录成功', icon: 'success' })

    // 获取并上报推送 CID（若可用）
    try {
      uni.getPushClientId({
        success: async (res: any) => {
          const cid = (res && (res.clientid || res.cid)) ? (res.clientid || res.cid) : (typeof res === 'string' ? res : null)
          if (cid != null && cid !== '') {
            try { uni.setStorageSync('uni_push2_cid', cid) } catch (e) {}
            try {
              const uidStored = uni.getStorageSync('user_id') || null
              const currentSession = supa.getSession()
              const currentUid = uidStored || (currentSession && currentSession.user ? currentSession.user.getString('id') : null)
              await AkReq.request({
                url: `${PUSH_SERVER_URL}/api/v1/push/register`,
                method: 'POST',
                data: { cid, platform: 'android', user_id: currentUid },
                contentType: 'application/json'
              })
              console.log('CID 已上报后台:', cid, 'user_id:', currentUid)
            } catch (e) { console.warn('上报 CID 失败:', e) }
          }
        },
        fail: (err: any) => { console.warn('获取 Push CID 失败:', err) }
      })
    } catch (e) {
      console.warn('getPushClientId 调用异常:', e)
    }

    // 成功跳转逻辑
    setTimeout(() => {
      const redirect = redirectPath.value
      if (redirect !== '') {
        navigateToRedirect(redirect)
      } else {
        goTargetHome()
      }
    }, 500)
  } catch (err) {
    console.error('登录错误:', err)
    let msg = '登录失败，请重试'
    // UTS 不支持 typeof 检查，直接尝试转换
    try {
      const e = err as Error
      if (e.message != null && e.message.trim() !== '') msg = e.message
    } catch (e2) {
      // 忽略转换错误，使用默认消息
    }
    uni.showToast({ title: msg, icon: 'none' })
  } finally {
    isLoading.value = false
  }
}

const navigateToRegister = (): void => {
  let url = '/pages/user/register'
  if (isDeliveryMode()) {
    url = '/pages/user/register?mode=delivery'
  } else if (isMerchantMode()) {
    url = '/pages/user/register?mode=merchant'
  }
  uni.navigateTo({
    url
  })
}
const handleTutorial = () => uni.showToast({ title: '扫码教程开发中', icon: 'none' })
const handleForgotPassword = () => uni.showToast({ title: '忘记密码开发中', icon: 'none' })
const handleWechatLogin = () => uni.showToast({ title: '微信登录开发中', icon: 'none' })
const handleQQLogin = () => uni.showToast({ title: 'QQ登录开发中', icon: 'none' })
</script>

<style scoped>
/* Base */
.page{
  /* min-height: 100vh; */ /* UVUE 不支持 vh */
  flex: 1;
  display: flex;
  flex-direction: column;
  background-color: #f5f6f8; /* UVUE 暂不支持 cssVars 在 style 标签中的变量引用 */
}

/* Header */
.header{
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  padding: 30px 40px; /* 调整边距 */
}
.logo{
  width: 240px;
  height: 64px;
}

/* Main */
.main{
  flex: 1;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  padding: 20px 10px;
}

/* Card */
.card{
  /* width: min(980px, 92vw); UVUE 不支持 min/vw */
  /* min-height: 460px; */
  width: 90%;
  background-color: #ffffff;
  border-radius: 16px;
  /* box-shadow: var(--shadow); */
  padding: 30px;
  display: flex;
  flex-direction: column; /* App端改为列式布局兼容性更好，或者用 row 需注意 */
  /* gap: 32px; UVUE 不支持 gap */
}

/* Left - 暂隐藏或简化 */
/* .left{ display: none; } */

.left{
  /* flex: 0 0 52%; UVUE flex 简写支持不全，建议用 flex-grow/basis */
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  /* padding-left: 18px; */
  display: none; /* 移动端 App 暂时隐藏扫码区 */
}
.left-title{
  font-size: 18px;
  font-weight: 700; /* 600 -> 700 */
  color: #333333;
  margin-bottom: 10px;
}
.left-hint{
  display: flex;
  flex-direction: row;
  align-items: center;
  /* gap: 14px; */
  margin-bottom: 18px;
}
/* 替代 gap */
.hint-text{ font-size: 13px; color: #666666; margin-right: 14px; }
.hint-link{ font-size: 13px; color: #e1251b; }

.qr-wrap{
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}
.qr{
  width: 240px;
  height: 240px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}
.qr-placeholder{
  width: 220px;
  height: 220px;
  border: 1px solid #e6e6e6;
  border-radius: 8px;
  background-color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* gap: 8px; */
}
/* 替代 gap */
.qr-text{ font-size: 14px; color: #666666; margin-bottom: 8px; }
.qr-sub{ font-size: 12px; color: #999999; }

/* Divider */
.divider{
  display: none; /* 移动端隐藏分割线 */
}

/* Right */
.right{
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.right-inner{
  /* width: 360px; */
  /* max-width: 100%; UVUE 不支持百分比 max-width */
  width: 100%;
  margin-left: auto;
}

/* Tabs */
.tabs{
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center; /* 移动端居中 */
  /* gap: 24px; */
  margin-bottom: 18px;
}
.tab{
  position: relative;
  padding: 8px 12px; /* 增加内边距替代 gap */
  margin: 0 12px;
}
.tab-text{
  font-size: 16px;
  color: #666666;
}
.tab.active .tab-text{
  color: #e1251b;
  font-weight: 700; /* 600 -> 700 */
}
.tab-line{
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 2px;
  background-color: #e1251b;
  border-radius: 2px;
}

/* Form */
.form{ margin-top: 10px; }
.field{ margin-bottom: 14px; }
.password-field {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
}
.eye-btn {
  position: absolute;
  right: 14px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
}
.eye-icon {
  font-size: 18px;
}
.input{
  width: 100%;
  height: 44px;
  line-height: 44px;
  border-radius: 10px;
  background-color: #f6f7f9;
  padding: 0 14px;
  font-size: 14px;
  color: #333333;
  box-sizing: border-box;
  display: flex;
  align-items: center;
}

/* Code row */
.code-row{
  display: flex;
  flex-direction: row;
  align-items: center;
  /* gap: 10px; */
}
.code-input{ flex: 1; margin-right: 10px; }
.code-btn{
  height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  background-color: #fff;
  border: 1px solid #eee;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}
.code-btn.disabled{ opacity: 0.5; }
.code-text{ font-size: 13px; color: #e1251b; }

/* Button */
.btn{
  margin-top: 16px;
  height: 46px;
  border-radius: 10px;
  background-color: rgba(225, 37, 27, 0.45); /* 注意 rgba 兼容性，建议用 hex 或 view opacity */
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}
.btn.disabled{ background-color: #d9d9d9; }
.btn-text{
  color: #fff;
  font-size: 16px;
  font-weight: 700; /* 600 -> 700 */
}

/* Actions：一行横排 */
.actions{
  margin-top: 16px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  /* gap: 12px; */
  flex-wrap: wrap; /* 允许换行 */
}
.action-item{
  display: flex;
  flex-direction: row;
  align-items: center;
  /* gap: 8px; */
  margin: 0 6px;
}
.dot{
  width: 16px;
  height: 16px;
  border-radius: 8px; /* 50% -> 8px (一半) */
  margin-right: 8px;
}
.dot.wechat{ background-color: #19be6b; }
.dot.qq{ background-color: #2d8cf0; }

.action-text{ font-size: 13px; color: #666666; }
.action-link{ font-size: 13px; color: #666666; margin: 0 6px; }
.sep{ font-size: 13px; color: #e0e0e0; margin: 0 6px; }

/* Footer */
.footer{
  padding: 18px 0 28px;
  display: flex;
  flex-direction: row;
  justify-content: center;
}
.footer-text{ font-size: 12px; color: #999999; }

/* ===== 自适应：移除复杂 Media Query，使用简单流式布局 ===== */
/*
@media screen and (max-width: 1024px){
  .header{ padding: 24px 20px; }
  .logo{ width: 240px; height: 68px; }
  .card{ width: 92vw; padding: 28px; gap: 22px; }
  .right-inner{ width: 360px; }
}
@media screen and (max-width: 768px){
  .card{ flex-direction: column; min-height: auto; }
  .left{ display: none; }
  .divider{ display: none; }
  .right-inner{ width: 100%; margin-left: 0; }
  .actions{ flex-wrap: wrap; }
}
@media screen and (max-width: 520px){
  .sep{ display: none; }
}
*/
</style>
