<template>
  <div class="relative">
    <!-- Scanner Container -->
    <div 
      :id="scannerId" 
      ref="scannerRef"
      class="w-full rounded-lg overflow-hidden bg-black"
      :class="{ 'aspect-video': !isScanning, 'min-h-[300px]': isScanning }"
    />

    <!-- Overlay when not scanning -->
    <div 
      v-if="!isScanning && !error" 
      class="absolute inset-0 flex items-center justify-center bg-gray-900 rounded-lg"
    >
      <div class="text-center">
        <UIcon name="i-heroicons-camera" class="w-16 h-16 text-gray-400 mb-4" />
        <UButton 
          color="primary" 
          size="lg"
          icon="i-heroicons-qr-code"
          @click="startScanning"
        >
          Start Camera
        </UButton>
      </div>
    </div>

    <!-- Error State -->
    <div 
      v-if="error" 
      class="absolute inset-0 flex items-center justify-center bg-gray-900 rounded-lg"
    >
      <div class="text-center px-4">
        <UIcon name="i-heroicons-exclamation-triangle" class="w-12 h-12 text-red-400 mb-4" />
        <p class="text-white mb-4">{{ error }}</p>
        <div class="flex gap-2 justify-center">
          <UButton @click="startScanning" color="primary">Try Again</UButton>
          <UButton @click="$emit('manual-entry')" color="gray">Enter Manually</UButton>
        </div>
      </div>
    </div>

    <!-- Manual Barcode Entry -->
    <div class="mt-4">
      <UFormGroup label="Or enter barcode manually">
        <div class="flex gap-2">
          <UInput 
            v-model="manualBarcode"
            placeholder="e.g. 8000500310427"
            size="lg"
            class="flex-1"
            @keyup.enter="submitManualBarcode"
          />
          <UButton 
            color="primary"
            size="lg"
            :disabled="!manualBarcode.trim()"
            @click="submitManualBarcode"
          >
            Lookup
          </UButton>
        </div>
      </UFormGroup>
    </div>
  </div>
</template>

<script setup lang="ts">
import { Html5Qrcode, Html5QrcodeSupportedFormats } from 'html5-qrcode'

const emit = defineEmits<{
  'barcode-detected': [barcode: string]
  'manual-entry': []
}>()

const scannerId = 'barcode-scanner'
const scannerRef = ref<HTMLElement | null>(null)
const isScanning = ref(false)
const error = ref<string | null>(null)
const manualBarcode = ref('')

let html5QrCode: Html5Qrcode | null = null

const startScanning = async () => {
  error.value = null

  try {
    if (!html5QrCode) {
      html5QrCode = new Html5Qrcode(scannerId, {
        formatsToSupport: [
          Html5QrcodeSupportedFormats.EAN_13,
          Html5QrcodeSupportedFormats.EAN_8,
          Html5QrcodeSupportedFormats.UPC_A,
          Html5QrcodeSupportedFormats.UPC_E,
          Html5QrcodeSupportedFormats.CODE_128,
          Html5QrcodeSupportedFormats.CODE_39,
          Html5QrcodeSupportedFormats.QR_CODE
        ],
        verbose: false
      })
    }

    await html5QrCode.start(
      { facingMode: 'environment' },
      {
        fps: 10,
        qrbox: { width: 250, height: 150 },
        aspectRatio: 1.777
      },
      onScanSuccess,
      onScanFailure
    )

    isScanning.value = true
  } catch (err: any) {
    console.error('Scanner error:', err)
    
    if (err.toString().includes('NotAllowedError')) {
      error.value = 'Camera permission denied. Please allow camera access and try again.'
    } else if (err.toString().includes('NotFoundError')) {
      error.value = 'No camera found. Please use a device with a camera or enter the barcode manually.'
    } else {
      error.value = 'Could not start camera. Try entering the barcode manually.'
    }
  }
}

const stopScanning = async () => {
  if (html5QrCode && isScanning.value) {
    try {
      await html5QrCode.stop()
    } catch (err) {
      console.error('Error stopping scanner:', err)
    }
    isScanning.value = false
  }
}

const onScanSuccess = (decodedText: string) => {
  // Stop scanning after successful read
  stopScanning()
  emit('barcode-detected', decodedText)
}

const onScanFailure = (_errorMessage: string) => {
  // Ignore - this fires continuously when no barcode is detected
}

const submitManualBarcode = () => {
  if (manualBarcode.value.trim()) {
    emit('barcode-detected', manualBarcode.value.trim())
    manualBarcode.value = ''
  }
}

// Cleanup on unmount
onUnmounted(() => {
  stopScanning()
})
</script>
