<script lang="ts" setup>
import QRCode from 'qrcode'

const props = withDefaults(defineProps<{
  value: string
  size?: number
}>(), {
  size: 220
})

const markup = ref('')
const renderError = ref('')

async function renderQrCode() {
  if (!props.value) {
    markup.value = ''
    renderError.value = ''
    return
  }

  try {
    markup.value = await QRCode.toString(props.value, {
      type: 'svg',
      errorCorrectionLevel: 'M',
      margin: 1,
      width: props.size
    })
    renderError.value = ''
  } catch (error: any) {
    markup.value = ''
    renderError.value = error?.message || 'Unable to generate QR code.'
  }
}

watch(
  () => [props.value, props.size],
  () => {
    void renderQrCode()
  },
  { immediate: true }
)
</script>

<template>
  <div class="inline-flex flex-col items-center gap-2">
    <div
      v-if="markup"
      class="overflow-hidden rounded-2xl border border-default bg-default p-4 shadow-sm"
    >
      <div
        class="[&>svg]:block [&>svg]:h-auto [&>svg]:w-full"
        :style="{ width: `${size}px` }"
        v-html="markup"
      />
    </div>

    <div
      v-else
      class="flex items-center justify-center rounded-2xl border border-dashed border-muted bg-elevated p-4 text-center text-sm text-muted"
      :style="{ width: `${size}px`, minHeight: `${size}px` }"
    >
      QR code unavailable
    </div>

    <p v-if="renderError" class="text-center text-xs text-error">
      {{ renderError }}
    </p>
  </div>
</template>
