"use client"

import { useState, useRef } from "react"
import Image from "next/image"
import { useMutation } from "convex/react"
import { api } from "../../../../../convex/_generated/api"
import type { Id } from "../../../../../convex/_generated/dataModel"
import { Button } from "@/components/ui/button"
import { Skeleton } from "@/components/ui/skeleton"
import { HugeiconsIcon } from "@hugeicons/react"
import { ImageUpload01Icon } from "@hugeicons/core-free-icons"
import { cn } from "@/lib/utils"

interface ImageUploadSectionProps {
  productId: Id<"products">
  nextPosition: number
  onSuccess: () => void
}

export function ImageUploadSection({
  productId,
  nextPosition,
  onSuccess,
}: ImageUploadSectionProps) {
  const [originalFile, setOriginalFile] = useState<File | null>(null)
  const [localUrl, setLocalUrl] = useState<string | null>(null)
  const [processedBlob, setProcessedBlob] = useState<Blob | null>(null)
  const [processedUrl, setProcessedUrl] = useState<string | null>(null)
  const [isProcessing, setIsProcessing] = useState(false)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [isSubmittingOriginal, setIsSubmittingOriginal] = useState(false)
  const [processingError, setProcessingError] = useState<string | null>(null)
  const [uploadError, setUploadError] = useState<string | null>(null)
  const [isDragging, setIsDragging] = useState(false)

  const fileInputRef = useRef<HTMLInputElement>(null)
  const addImage = useMutation(api.products.addImage)

  async function processFile(file: File) {
    if (localUrl) URL.revokeObjectURL(localUrl)
    if (processedUrl) URL.revokeObjectURL(processedUrl)

    setOriginalFile(file)
    setLocalUrl(URL.createObjectURL(file))
    setProcessedBlob(null)
    setProcessedUrl(null)
    setProcessingError(null)
    setUploadError(null)
    setIsProcessing(true)

    const baseUrl =
      process.env.NEXT_PUBLIC_IMAGE_PROCESSING_API_URL ?? "http://localhost:8000"
    const formData = new FormData()
    formData.append("file", file)
    formData.append("format", "webp")
    formData.append("quality", "95")

    try {
      const res = await fetch(`${baseUrl}/api/remove-background`, {
        method: "POST",
        body: formData,
      })

      if (!res.ok) {
        const errJson = (await res.json().catch(() => ({}))) as { detail?: string }
        throw new Error(errJson.detail ?? "Background removal failed")
      }

      const blob = await res.blob()
      setProcessedBlob(blob)
      setProcessedUrl(URL.createObjectURL(blob))
    } catch (err) {
      setProcessingError(err instanceof Error ? err.message : "Processing failed")
    } finally {
      setIsProcessing(false)
    }
  }

  function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0]
    if (file) processFile(file)
    e.target.value = ""
  }

  function handleDrop(e: React.DragEvent) {
    e.preventDefault()
    setIsDragging(false)
    const file = e.dataTransfer.files?.[0]
    if (file && file.type.startsWith("image/")) processFile(file)
  }

  async function uploadBlob(blob: Blob, filename: string) {
    const uploadForm = new FormData()
    uploadForm.append("file", blob, filename)
    uploadForm.append("productId", productId)
    uploadForm.append("position", String(nextPosition))

    const uploadRes = await fetch("/api/upload-image", {
      method: "POST",
      body: uploadForm,
    })

    if (!uploadRes.ok) {
      const errJson = (await uploadRes.json().catch(() => ({}))) as { error?: string }
      throw new Error(errJson.error ?? "Upload failed")
    }

    const { url } = await uploadRes.json()
    return url as string
  }

  async function handleSubmit() {
    if (!processedBlob) return
    setIsSubmitting(true)
    setUploadError(null)

    try {
      const url = await uploadBlob(processedBlob, "product-image.webp")
      await addImage({ productId, url, position: nextPosition })
      onSuccess()
    } catch (err) {
      setUploadError(err instanceof Error ? err.message : "Upload failed")
    } finally {
      setIsSubmitting(false)
    }
  }

  async function handleSubmitOriginal() {
    if (!originalFile) return
    setIsSubmittingOriginal(true)
    setUploadError(null)

    try {
      const url = await uploadBlob(originalFile, originalFile.name)
      await addImage({ productId, url, position: nextPosition })
      onSuccess()
    } catch (err) {
      setUploadError(err instanceof Error ? err.message : "Upload failed")
    } finally {
      setIsSubmittingOriginal(false)
    }
  }

  return (
    <div className="space-y-4">
      {/* Drop zone */}
      <div
        className={cn(
          "flex cursor-pointer flex-col items-center justify-center gap-2 rounded-md border border-dashed p-8 transition-colors",
          isDragging
            ? "border-foreground/60 bg-muted"
            : "hover:border-foreground/40 hover:bg-muted/50",
        )}
        onClick={() => fileInputRef.current?.click()}
        onDragOver={(e) => {
          e.preventDefault()
          setIsDragging(true)
        }}
        onDragLeave={() => setIsDragging(false)}
        onDrop={handleDrop}
        role="button"
        tabIndex={0}
        aria-label="Select or drop an image file"
        onKeyDown={(e) => e.key === "Enter" && fileInputRef.current?.click()}
      >
        <HugeiconsIcon
          icon={ImageUpload01Icon}
          strokeWidth={2}
          className="size-8 text-muted-foreground"
        />
        <div className="text-center">
          <p className="text-sm font-medium">Click to select or drag and drop</p>
          <p className="text-xs text-muted-foreground">PNG, JPEG, WebP</p>
        </div>
      </div>

      <input
        ref={fileInputRef}
        type="file"
        accept="image/png,image/jpeg,image/webp"
        className="sr-only"
        onChange={handleFileChange}
        aria-label="Image file input"
      />

      {/* Side-by-side previews */}
      {(localUrl || isProcessing) && (
        <div className="grid grid-cols-2 gap-4">
          <div className="space-y-1">
            <p className="text-xs font-medium text-muted-foreground">Original</p>
            {localUrl && (
              <div className="relative aspect-square overflow-hidden rounded-md border bg-muted">
                <Image
                  src={localUrl}
                  alt="Original"
                  fill
                  className="object-contain"
                  unoptimized
                />
              </div>
            )}
          </div>

          <div className="space-y-1">
            <p className="text-xs font-medium text-muted-foreground">Background removed</p>
            {isProcessing ? (
              <Skeleton className="aspect-square w-full rounded-md" />
            ) : processedUrl ? (
              <div className="relative aspect-square overflow-hidden rounded-md border bg-[conic-gradient(#e5e7eb_25%,_#fff_25%,_#fff_50%,_#e5e7eb_50%,_#e5e7eb_75%,_#fff_75%)] bg-[length:16px_16px]">
                <Image
                  src={processedUrl}
                  alt="Background removed"
                  fill
                  className="object-contain"
                  unoptimized
                />
              </div>
            ) : processingError ? (
              <div className="flex aspect-square items-center justify-center rounded-md border bg-muted p-4">
                <p className="text-center text-xs text-destructive">{processingError}</p>
              </div>
            ) : null}
          </div>
        </div>
      )}

      {uploadError && <p className="text-sm text-destructive">{uploadError}</p>}

      <div className="flex items-center gap-2">
        <Button
          onClick={handleSubmit}
          disabled={!processedBlob || isSubmitting || isSubmittingOriginal}
        >
          {isSubmitting && (
            <svg
              data-icon="inline-start"
              className="animate-spin"
              viewBox="0 0 24 24"
              fill="none"
              aria-hidden="true"
            >
              <circle
                className="opacity-25"
                cx="12"
                cy="12"
                r="10"
                stroke="currentColor"
                strokeWidth="4"
              />
              <path
                className="opacity-75"
                fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
              />
            </svg>
          )}
          {isSubmitting ? "Uploading…" : "Upload processed"}
        </Button>

        <Button
          variant="outline"
          onClick={handleSubmitOriginal}
          disabled={!originalFile || isSubmitting || isSubmittingOriginal}
        >
          {isSubmittingOriginal && (
            <svg
              data-icon="inline-start"
              className="animate-spin"
              viewBox="0 0 24 24"
              fill="none"
              aria-hidden="true"
            >
              <circle
                className="opacity-25"
                cx="12"
                cy="12"
                r="10"
                stroke="currentColor"
                strokeWidth="4"
              />
              <path
                className="opacity-75"
                fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
              />
            </svg>
          )}
          {isSubmittingOriginal ? "Uploading…" : "Upload original"}
        </Button>
      </div>
    </div>
  )
}
