<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { useGoogleAuthStore } from '@/stores/googleAuth'
import { useAuthStore } from '@/stores/auth'
import { useToast } from '@/composables/useToast'
import { useI18n } from 'vue-i18n'
import { qrCodeImageUrl } from '@/utils/qr'
import { maskEmailForDisplay } from '@/utils/maskEmail'
import { copyTextToClipboard, isMacChrome } from '@/utils/clipboard'

const { t } = useI18n()
const router = useRouter()
const googleStore = useGoogleAuthStore()
const authStore = useAuthStore()
const { secret, otpauthUrl, isSecretLoading, sendingCode, submitting, codeCountdown } =
  storeToRefs(googleStore)
const toast = useToast()

const googleCode = ref('')
const emailCode = ref('')
const localError = ref('')

const maskedEmail = computed(() => {
  const raw = authStore.memberProfile?.email ?? authStore.email ?? ''
  return maskEmailForDisplay(raw)
})

const qrSrc = ref('')
watch(otpauthUrl, async (url) => { qrSrc.value = url ? await qrCodeImageUrl(url, 200) : '' }, { immediate: true })

onMounted(async () => {
  if (!authStore.memberProfile) {
    try {
      await authStore.fetchMyInfo()
    } catch {
      // 邮箱展示降级为 auth.email
    }
  }
  localError.value = ''
  try {
    await googleStore.fetchSecret()
  } catch {
    localError.value = googleStore.error ?? t('common.loadFailed')
  }
})

onUnmounted(() => {
  googleStore.resetLocal()
})

async function copySecret() {
  if (!secret.value) return
  const result = await copyTextToClipboard(secret.value)
  if (result === 'success') {
    toast.success(t('security.keyCopied'))
    return
  }
  if (result === 'denied') {
    toast.error(isMacChrome() ? t('security.clipboardDeniedMac') : t('security.clipboardDenied'))
    return
  }
  toast.error(t('security.copyFailed'))
}

async function onSendEmail() {
  localError.value = ''
  try {
    await googleStore.sendEmailCode()
    toast.success(t('security.emailCodeSent'))
  } catch {
    localError.value = googleStore.error ?? t('error.sendFailed')
  }
}

async function onBind() {
  localError.value = ''
  if (googleCode.value.length !== 6) {
    localError.value = t('security.googleCodeRequired')
    return
  }
  if (!/^\d{6}$/.test(emailCode.value)) {
    localError.value = t('error.sixDigitCode')
    return
  }
  if (!secret.value) {
    localError.value = t('security.invalidSecret')
    return
  }
  try {
    await googleStore.bindGoogleAuth(googleCode.value, emailCode.value, secret.value)
    toast.success(t('security.bindSuccess'))
    router.replace('/account/security')
  } catch {
    localError.value = googleStore.error ?? t('error.operationFailed')
  }
}
</script>

<template>
  <main class="page-main">
    <div class="page-container sub-wrap">
      <div class="page-header">
        <RouterLink to="/account/security/google-auth" class="back-link">{{ t('security.back') }}</RouterLink>
        <h1 class="page-title">{{ t('security.bindGoogle') }}</h1>
      </div>

      <div v-if="isSecretLoading && !secret" class="loading-state">
        <div class="spinner" />
      </div>

      <div v-else class="form-card dark-card">
        <p class="email-line">{{ t('security.boundEmail') }}<strong>{{ maskedEmail }}</strong></p>

        <section class="block">
          <h3 class="block-title">{{ t('security.googleQrStep') }}</h3>
          <div v-if="qrSrc" class="qr-wrap">
            <img :src="qrSrc" alt="Authenticator QR" class="qr-img" width="200" height="200" />
          </div>
          <div class="secret-row">
            <code class="secret-key">{{ secret || '—' }}</code>
            <button type="button" class="link-btn" @click="copySecret">{{ t('security.copyKey') }}</button>
          </div>
        </section>

        <section class="block">
          <h3 class="block-title">{{ t('security.googleCodeStep') }}</h3>
          <input
            v-model="googleCode"
            type="text"
            maxlength="6"
            class="form-input"
            placeholder="000000"
            @input="googleCode = googleCode.replace(/\D/g, '')"
          />
        </section>

        <section class="block">
          <h3 class="block-title">{{ t('security.emailCodeStep') }}</h3>
          <div class="code-row">
            <input
              v-model="emailCode"
              type="text"
              maxlength="6"
              class="form-input"
              placeholder="6"
              @input="emailCode = emailCode.replace(/\D/g, '')"
            />
            <button
              type="button"
              class="send-code-btn"
              :disabled="sendingCode || codeCountdown > 0"
              @click="onSendEmail"
            >
              {{ codeCountdown > 0 ? `${codeCountdown}s` : t('security.sendCode') }}
            </button>
          </div>
        </section>

        <p v-if="localError" class="form-error">{{ localError }}</p>

        <div class="actions">
          <button type="button" class="btn-cancel" @click="router.back()">{{ t('common.cancel') }}</button>
          <button type="button" class="btn-confirm" :disabled="submitting" @click="onBind">
            {{ submitting ? t('security.submitting') : t('security.confirmBind') }}
          </button>
        </div>
      </div>
    </div>
  </main>
</template>

<style scoped>
.sub-wrap {
  padding-top: var(--space-8);
  padding-bottom: var(--space-16);
  max-width: 520px;
}
.page-header {
  margin-bottom: var(--space-8);
}
.back-link {
  font-size: var(--text-small);
  color: var(--color-text-secondary);
  display: inline-block;
  margin-bottom: var(--space-3);
}
.page-title {
  font-size: var(--text-h1);
  font-weight: var(--fw-bold);
  color: var(--color-text-primary);
}
.loading-state {
  display: flex;
  justify-content: center;
  padding: var(--space-16);
}
.spinner {
  width: 32px;
  height: 32px;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
.form-card {
  padding: var(--space-6);
}
.email-line {
  font-size: var(--text-small);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-6);
}
.block {
  margin-bottom: var(--space-6);
}
.block-title {
  font-size: var(--text-small);
  font-weight: var(--fw-semibold);
  color: var(--color-text-primary);
  margin-bottom: var(--space-3);
}
.qr-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: var(--space-4);
}
.qr-img {
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
}
.secret-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.secret-key {
  flex: 1;
  min-width: 0;
  font-family: var(--font-family-num);
  font-size: var(--text-small);
  padding: var(--space-2) var(--space-3);
  background: rgba(240, 185, 11, 0.08);
  border-radius: var(--radius-sm);
  word-break: break-all;
}
.link-btn {
  background: transparent;
  border: none;
  color: var(--color-primary);
  cursor: pointer;
  font-size: var(--text-small);
}
.form-input {
  width: 100%;
  box-sizing: border-box;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  color: var(--color-text-primary);
  letter-spacing: 0.2em;
  outline: none;
}
.form-error {
  font-size: var(--text-small);
  color: var(--color-down);
  margin-bottom: var(--space-4);
}
.code-row {
  display: flex;
  gap: var(--space-3);
}
.code-row .form-input {
  flex: 1;
  letter-spacing: normal;
}
.send-code-btn {
  white-space: nowrap;
  padding: 0 var(--space-4);
  background: transparent;
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-md);
  color: var(--color-primary);
  font-size: var(--text-small);
  cursor: pointer;
  flex-shrink: 0;
}
.send-code-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.actions {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-6);
}
.btn-cancel {
  flex: 1;
  padding: var(--space-3);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text-secondary);
  cursor: pointer;
}
.btn-confirm {
  flex: 2;
  padding: var(--space-3);
  background: var(--color-primary);
  border: none;
  border-radius: var(--radius-md);
  color: #000;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.btn-confirm:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
</style>
