<script lang="ts">
  import { onMount, onDestroy } from 'svelte';

  interface Props {
    onCapture: (file: File) => void;
  }

  let { onCapture }: Props = $props();

  let video: HTMLVideoElement;
  let stream: MediaStream | null = null;
  let error: string | null = $state(null);
  let ready = $state(false);

  onMount(async () => {
    try {
      stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: 'environment' },
        audio: false,
      });
      video.srcObject = stream;
      await video.play();
      ready = true;
    } catch (err) {
      error =
        err instanceof DOMException && err.name === 'NotAllowedError'
          ? 'Camera permission denied. Please allow camera access in your browser settings.'
          : err instanceof Error
            ? err.message
            : 'Could not access camera.';
    }
  });

  onDestroy(() => {
    stream?.getTracks().forEach((t) => t.stop());
  });

  function capture() {
    if (!ready || !video.videoWidth) return;
    const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;
    ctx.drawImage(video, 0, 0);
    canvas.toBlob(
      (blob) => {
        if (blob) {
          const file = new File([blob], 'capture.jpg', { type: 'image/jpeg' });
          onCapture(file);
        }
      },
      'image/jpeg',
      0.9,
    );
  }
</script>

<div class="camera-container">
  {#if error}
    <div class="camera-error">
      <div class="error-icon">📷</div>
      <p>{error}</p>
    </div>
  {:else}
    <video
      bind:this={video}
      class="camera-video"
      autoplay
      playsinline
      muted
    ></video>

    {#if ready}
      <div class="capture-overlay">
        <div class="reticle"></div>
        <button class="capture-btn" onclick={capture} aria-label="Take photo">
          <div class="capture-ring"></div>
        </button>
        <p class="hint">Point at an object and tap to scan</p>
      </div>
    {:else}
      <div class="camera-loading">
        <div class="spinner"></div>
        <p>Starting camera…</p>
      </div>
    {/if}
  {/if}
</div>

<style>
  .camera-container {
    position: relative;
    width: 100%;
    height: 100%;
    background: #000;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .camera-video {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .capture-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    padding-bottom: 2rem;
    pointer-events: none;
  }

  .reticle {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 200px;
    height: 200px;
    border: 2px solid rgba(255, 255, 255, 0.4);
    border-radius: 16px;
    pointer-events: none;
  }

  .capture-btn {
    width: 72px;
    height: 72px;
    border: none;
    background: none;
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: auto;
    -webkit-tap-highlight-color: transparent;
  }

  .capture-ring {
    width: 64px;
    height: 64px;
    border: 4px solid white;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.3);
    transition: all 0.15s;
  }

  .capture-btn:active .capture-ring {
    transform: scale(0.85);
    background: rgba(255, 255, 255, 0.6);
  }

  .hint {
    color: rgba(255, 255, 255, 0.7);
    font-size: 0.85rem;
    margin-top: 0.75rem;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
  }

  .camera-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    color: white;
  }

  .spinner {
    width: 40px;
    height: 40px;
    border: 3px solid rgba(255, 255, 255, 0.2);
    border-top-color: white;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }

  @keyframes spin {
    to { transform: rotate(360deg); }
  }

  .camera-error {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    color: white;
    text-align: center;
    padding: 2rem;
  }

  .error-icon {
    font-size: 3rem;
  }
</style>
