<script setup>
import { onBeforeUnmount, ref, watch } from 'vue'
import { useUserMedia } from '@vueuse/core'

const props = defineProps({
  deviceId: { type: String, default: '' },
})

const emit = defineEmits(['error'])

const videoRef = ref(null)

const errorMessage = ref('')

const { stream, start, restart, stop, constraints } = useUserMedia({
  enabled: false,
  autoSwitch: true,
  constraints: { video: { facingMode: 'user' }, audio: false },
})

async function ensureStream() {
  try {
    if (stream.value) {
      await restart()
    } else {
      await start()
    }
    errorMessage.value = ''
  } catch (err) {
    errorMessage.value = err?.message || 'Camera access failed.'
    emit('error', err)
  }
}

watch(
  () => props.deviceId,
  async (value) => {
    constraints.value = {
      video: value ? { deviceId: { exact: value } } : { facingMode: 'user' },
      audio: false,
    }
    await ensureStream()
  },
  { immediate: true },
)

watch(stream, (value) => {
  if (videoRef.value && value) {
    videoRef.value.srcObject = value
    videoRef.value.play().catch(() => {})
  }
})

onBeforeUnmount(() => {
  stop()
})

function takeSnapshot() {
  const video = videoRef.value
  if (!video) return null

  const videoWidth = video.videoWidth || 1360
  const videoHeight = video.videoHeight || 768

  // Crop to 3:2 aspect ratio (matches template photo slots: 440×290 pixels = 1.517:1)
  const targetRatio = 3 / 2
  const videoRatio = videoWidth / videoHeight

  let cropWidth = videoWidth
  let cropHeight = videoHeight
  let cropX = 0
  let cropY = 0

  if (videoRatio > targetRatio) {
    // Video is wider than target, crop width
    cropWidth = videoHeight * targetRatio
    cropX = (videoWidth - cropWidth) / 2
  } else {
    // Video is taller than target, crop height
    cropHeight = videoWidth / targetRatio
    cropY = (videoHeight - cropHeight) / 2
  }

  const canvas = document.createElement('canvas')
  canvas.width = cropWidth
  canvas.height = cropHeight

  const ctx = canvas.getContext('2d')
  if (!ctx) return null

  ctx.drawImage(video, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight)
  return canvas.toDataURL('image/png')
}

defineExpose({ takeSnapshot })
</script>

<template>
  <div class="camera-shell">
    <video ref="videoRef" class="camera-video" autoplay playsinline muted></video>
    <div v-if="errorMessage" class="camera-fallback">
      <p>Camera access is blocked. Please allow permissions and refresh.</p>
    </div>
  </div>
</template>

<style scoped>
.camera-shell {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 32px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.7);
  box-shadow: 0 18px 50px rgba(203, 115, 140, 0.2);
}

.camera-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
}

.camera-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  text-align: center;
  color: #7a3b4f;
  background: rgba(255, 235, 243, 0.92);
}
</style>
