"use client"

import React from "react"
import { useRef, useState } from "react"
import { ImagePlus, X, Upload } from "lucide-react"
import { MAX_CMS_PAGE_IMAGE_SIZE_BYTES } from "@/lib/media-manager/cms-page-pending"
import { stageImage, revokeStagedImage } from "@/lib/media-manager/stage"
import type { StagedImage } from "@/lib/media-manager/types"
import { validateLocalImageFile } from "@/lib/media-manager/local-upload-policy"

interface InlineImageUploaderProps {
  label?: string
  value: string
  fallbackValue?: string
  onChange: (url: string) => void
  /** Called when user selects a file — image stays local until form save. */
  onStageImage: (staged: StagedImage) => void
  onClearStagedImage?: () => void
  /** Base name for R2 file (e.g. Services, heroimage). */
  fileBaseName: string
  /** Zero-based index for numbered files (Services1, Services2, …). */
  fileIndex?: number
  height?: string
  disabled?: boolean
}

export function InlineImageUploader({
  label,
  value,
  fallbackValue,
  onChange,
  onStageImage,
  onClearStagedImage,
  fileBaseName,
  fileIndex,
  height = "h-36",
  disabled = false,
}: InlineImageUploaderProps) {
  const inputRef = useRef<HTMLInputElement>(null)
  const [dragOver, setDragOver] = useState(false)
  const [error, setError] = useState<string | null>(null)

  function handleFile(file: File) {
    if (disabled) return
    setError(null)
    if (!file.type.startsWith("image/")) {
      setError("Please upload a valid image file.")
      return
    }
    const fileError = validateLocalImageFile(file, MAX_CMS_PAGE_IMAGE_SIZE_BYTES)
    if (fileError) {
      setError(fileError)
      return
    }
    try {
      onClearStagedImage?.()
      const staged = stageImage(file, {
        maxBytes: MAX_CMS_PAGE_IMAGE_SIZE_BYTES,
        fileBaseName,
        fileIndex,
      })
      onStageImage(staged)
      onChange(staged.previewUrl)
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to prepare image.")
    }
  }

  function handleRemove() {
    onClearStagedImage?.()
    onChange("")
  }

  function handleDrop(e: React.DragEvent) {
    if (disabled) return
    e.preventDefault()
    setDragOver(false)
    const file = e.dataTransfer.files[0]
    if (file) handleFile(file)
  }

  const effectiveValue = value.trim() || fallbackValue?.trim() || ""
  const isUsingFallback = !value.trim() && !!fallbackValue?.trim()
  const isBlobPreview = value.startsWith("blob:")

  return (
    <div className="flex flex-col gap-1.5">
      {label && (
        <label className="text-xs font-semibold text-muted-foreground font-sans">
          {label}
        </label>
      )}

      {effectiveValue ? (
        <div className={`relative rounded-xl overflow-hidden border border-border bg-card ${height}`}>
          <img
            src={effectiveValue}
            alt="Preview"
            className="w-full h-full object-cover"
          />
          <button
            type="button"
            disabled={disabled}
            onClick={handleRemove}
            className="absolute top-2 right-2 w-7 h-7 rounded-lg bg-black/60 flex items-center justify-center text-white hover:bg-black/80 transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
            aria-label="Remove image"
          >
            <X className="w-3.5 h-3.5" aria-hidden="true" />
          </button>
          {isUsingFallback && (
            <div className="absolute bottom-2 left-2 px-2 py-1 rounded-md text-[10px] font-semibold text-white bg-black/60">
              Using English shared image
            </div>
          )}
          {isBlobPreview && (
            <div className="absolute bottom-2 right-2 px-2 py-1 rounded-md text-[10px] font-semibold text-white bg-black/60">
              Not saved yet
            </div>
          )}
        </div>
      ) : (
        <div
          role="button"
          tabIndex={disabled ? -1 : 0}
          onClick={() => !disabled && inputRef.current?.click()}
          onKeyDown={(e) => !disabled && e.key === "Enter" && inputRef.current?.click()}
          onDragOver={(e) => {
            e.preventDefault()
            setDragOver(true)
          }}
          onDragLeave={() => setDragOver(false)}
          onDrop={handleDrop}
          className={`flex flex-col items-center justify-center gap-2 ${height} rounded-xl border-2 border-dashed transition-all ${disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}
          style={{
            borderColor: dragOver ? "var(--brand-green)" : "var(--border)",
            background: dragOver ? "rgba(43,182,115,0.04)" : "var(--card)",
          }}
          aria-label={label ? `Upload ${label}` : "Upload image"}
        >
          <div
            className="w-9 h-9 rounded-xl flex items-center justify-center"
            style={{ background: "rgba(43,182,115,0.10)" }}
          >
            <ImagePlus className="w-4.5 h-4.5" style={{ color: "var(--brand-green)" }} aria-hidden="true" />
          </div>
          <div className="text-center">
            <p className="text-xs font-semibold text-foreground font-sans flex items-center gap-1 justify-center">
              <Upload className="w-3 h-3" aria-hidden="true" />
              Click or drag to select
            </p>
            <p className="text-[11px] text-muted-foreground font-sans mt-0.5">
              Saved when you save the page
            </p>
          </div>
        </div>
      )}

      {error && (
        <p className="text-xs font-sans text-red-500" role="alert">
          {error}
        </p>
      )}

      <input
        ref={inputRef}
        type="file"
        accept="image/*"
        disabled={disabled}
        className="sr-only"
        aria-hidden="true"
        onChange={(e) => {
          const file = e.target.files?.[0]
          if (file) handleFile(file)
          e.target.value = ""
        }}
      />
    </div>
  )
}

/** Revoke blob URL if this value is a local preview (safe on clear/unmount). */
export function revokeInlinePreviewUrl(url: string) {
  if (!url.startsWith("blob:")) return
  try {
    URL.revokeObjectURL(url)
  } catch {
    /* ignore */
  }
}
