"use client"

import { useRef, useState, useCallback, useEffect } from "react"
import { Camera, ImagePlus, X, Loader2 } from "lucide-react"
import { Button } from "@/components/ui/button"
import { CameraCapture } from "@/components/scan/camera-capture"
import { cn } from "@/lib/utils"

interface DrinkImageUploadProps {
  imageUrl?: string | null
  onImageChange: (url: string | null) => void
}

export function DrinkImageUpload({
  imageUrl,
  onImageChange,
}: DrinkImageUploadProps) {
  const [isUploading, setIsUploading] = useState(false)
  const [dragActive, setDragActive] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [showCamera, setShowCamera] = useState(false)
  const [hasGetUserMedia, setHasGetUserMedia] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const cameraInputRef = useRef<HTMLInputElement>(null)

  // getUserMedia needs a secure context, so it is absent when the app is reached
  // over plain http on the LAN. Checked after mount because it is not available
  // during server rendering.
  useEffect(() => {
    setHasGetUserMedia(
      typeof navigator !== "undefined" && !!navigator.mediaDevices?.getUserMedia
    )
  }, [])

  const uploadFile = useCallback(
    async (file: File) => {
      setError(null)
      setIsUploading(true)

      try {
        const formData = new FormData()
        formData.append("file", file)

        const res = await fetch("/api/upload", {
          method: "POST",
          body: formData,
        })

        if (!res.ok) {
          const body = await res.json().catch(() => ({}))
          throw new Error(body.error || "Failed to upload image")
        }

        const { url } = await res.json()
        onImageChange(url)
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to upload image")
      } finally {
        setIsUploading(false)
      }
    },
    [onImageChange]
  )

  const handleFile = useCallback(
    (file: File) => {
      if (!file.type.startsWith("image/")) {
        setError("Please select an image file")
        return
      }
      uploadFile(file)
    },
    [uploadFile]
  )

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault()
      setDragActive(false)
      const file = e.dataTransfer.files[0]
      if (file) {
        handleFile(file)
      }
    },
    [handleFile]
  )

  const handleRemove = () => {
    onImageChange(null)
    setError(null)
    if (fileInputRef.current) fileInputRef.current.value = ""
    if (cameraInputRef.current) cameraInputRef.current.value = ""
  }

  if (showCamera) {
    return (
      <CameraCapture
        onCapture={(file) => {
          setShowCamera(false)
          handleFile(file)
        }}
        onClose={() => setShowCamera(false)}
      />
    )
  }

  if (imageUrl) {
    return (
      <div className="relative">
        <img
          src={imageUrl}
          alt="Drink photo"
          className="w-full rounded-lg max-h-[300px] object-contain bg-muted"
        />
        <Button
          type="button"
          variant="destructive"
          size="icon"
          className="absolute top-2 right-2"
          onClick={handleRemove}
        >
          <X className="h-4 w-4" />
        </Button>
      </div>
    )
  }

  return (
    <div>
      <div
        className={cn(
          "border-2 border-dashed rounded-lg transition-colors",
          dragActive
            ? "border-primary bg-primary/5"
            : "border-muted-foreground/25",
          isUploading && "pointer-events-none opacity-60"
        )}
        onDragOver={(e) => {
          e.preventDefault()
          setDragActive(true)
        }}
        onDragLeave={() => setDragActive(false)}
        onDrop={handleDrop}
      >
        <div className="flex flex-col items-center gap-3 py-8">
          {isUploading ? (
            <>
              <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
              <p className="text-sm text-muted-foreground">Uploading...</p>
            </>
          ) : (
            <>
              <ImagePlus className="h-8 w-8 text-muted-foreground" />
              <div className="flex flex-wrap items-center justify-center gap-2">
                <Button
                  type="button"
                  size="sm"
                  className="gap-2"
                  onClick={() => {
                    // Without getUserMedia, fall back to the file input's capture
                    // hint, which opens the camera app on mobile.
                    if (hasGetUserMedia) setShowCamera(true)
                    else cameraInputRef.current?.click()
                  }}
                >
                  <Camera className="h-4 w-4" />
                  Take Photo
                </Button>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={() => fileInputRef.current?.click()}
                >
                  Upload Photo
                </Button>
              </div>
              <p className="text-xs text-muted-foreground text-center">
                or drag and drop an image here
              </p>
            </>
          )}
        </div>
      </div>

      {error && <p className="text-sm text-destructive mt-1.5">{error}</p>}

      <input
        ref={cameraInputRef}
        type="file"
        accept="image/jpeg,image/png,image/webp,image/heic"
        capture="environment"
        className="hidden"
        onChange={(e) => {
          const file = e.target.files?.[0]
          if (file) handleFile(file)
        }}
      />
      <input
        ref={fileInputRef}
        type="file"
        accept="image/jpeg,image/png,image/webp,image/heic"
        className="hidden"
        onChange={(e) => {
          const file = e.target.files?.[0]
          if (file) handleFile(file)
        }}
      />
    </div>
  )
}
