<template>
  <div>
    <t-form labelWidth="0">
      <t-form-item>
        <t-input v-model="username" placeholder="请输入用户名"></t-input>
      </t-form-item>
      <t-form-item>
        <t-input v-model="password" placeholder="请输入密码"></t-input>
      </t-form-item>
      <t-space class="login-button-box" direction="vertical" size="small">
        <t-button class="login-button" theme="primary" :loading="loading" @click="handleLogin"
          >登录</t-button
        >
        <t-button
          class="login-button"
          theme="default"
          :disabled="!passkey"
          @click="handleUsePasskey"
          >使用通行密钥</t-button
        >
        <t-link @click="handleRegister">没有账号？去注册</t-link>
      </t-space>
    </t-form>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, toRefs } from 'vue'
import { assertion, assertion_options, login } from '@/api/auth.ts'

const emits = defineEmits(['complete', 'register'])
const { username, password } = toRefs(
  reactive({
    username: '',
    password: '',
  }),
)

const loading = ref(false)
function handleLogin() {
  loading.value = true
  login({ user: username.value, password: password.value })
    .then((x: any) => {
      if (x.code === 200) {
        emits('complete')
      }
    })
    .catch((e: any) => {
      console.error(e)
    })
    .finally(() => {
      loading.value = false
    })
}

const passkey = ref(true)

if (!navigator.credentials) {
  passkey.value = false
}
function base64ToArrayBuffer(base64: string): ArrayBuffer {
  // 处理base64url格式：替换字符并添加填充
  let normalizedBase64 = base64.replace(/-/g, '+').replace(/_/g, '/')
  // 添加必要的填充
  while (normalizedBase64.length % 4 !== 0) {
    normalizedBase64 += '='
  }

  try {
    const binaryString = atob(normalizedBase64)
    const bytes = new Uint8Array(binaryString.length)
    for (let i = 0; i < binaryString.length; i++) {
      bytes[i] = binaryString.charCodeAt(i)
    }
    return bytes.buffer
  } catch (e) {
    console.error('Base64 decoding failed:', e, 'Input was:', base64)
    throw e
  }
}
function handleUsePasskey() {
  assertion_options().then((x: any) => {
    const parse = JSON.parse(x.data)
    parse.publicKey.challenge = base64ToArrayBuffer(parse.publicKey?.challenge)
    console.log(parse)
    navigator.credentials.get(parse).then((x: any) => {
      assertion(x).then((x: any) => {
        if (x.code === 200) {
          emits('complete')
        }
      })
    })
  })
  // emits('complete')
}
function handleRegister() {
  emits('register')
}
</script>

<style scoped lang="scss">
.login-button-box {
  width: 100%;
  .login-button {
    display: block;
    width: 100%;
  }
}
</style>
