<template>
  <div class="h-dvh flex flex-col" :class="currentTheme">
    <RouterView />
    <ArticleOverlay />
    <PassphraseDialog
      :visible="showPassphrase"
      :is-creating="isCreatingPassphrase"
      @submit="handlePassphraseSubmit"
      @skip="showPassphrase = false"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { RouterView } from 'vue-router'
import { useTheme } from '@/composables/useTheme'
import ArticleOverlay from '@/components/content/ArticleOverlay.vue'
import PassphraseDialog from '@/components/ui/PassphraseDialog.vue'
import {
  isCryptoEnabled,
  deriveKey,
  generateSalt,
  setSessionKey,
} from '@/utils/crypto'

const { currentTheme, initTheme } = useTheme()

const showPassphrase = ref(false)
const isCreatingPassphrase = ref(false)

const SALT_KEY = 'aiui-crypto-salt'

async function handlePassphraseSubmit(passphrase: string) {
  let saltHex = localStorage.getItem(SALT_KEY)
  let salt: Uint8Array

  if (saltHex) {
    salt = new Uint8Array(saltHex.match(/.{2}/g)!.map(b => parseInt(b, 16)))
  } else {
    salt = await generateSalt()
    saltHex = Array.from(salt).map(b => b.toString(16).padStart(2, '0')).join('')
    localStorage.setItem(SALT_KEY, saltHex)
  }

  const key = await deriveKey(passphrase, salt)
  setSessionKey(key, salt)
  showPassphrase.value = false
}

onMounted(() => {
  initTheme()
  if (isCryptoEnabled()) {
    const hasSalt = !!localStorage.getItem(SALT_KEY)
    isCreatingPassphrase.value = !hasSalt
    showPassphrase.value = true
  }
})
</script>
