"use client";

import { useRef, useState, useCallback } from "react";
import { Image, X, Upload } from "lucide-react";

// ============================================
// Image Picker Component
// Reusable image selection with preview.
// Stores image as base64 data URL in state.
// ============================================

interface ImagePickerProps {
  value: string | null;
  onChange: (value: string | null) => void;
  label?: string;
  required?: boolean;
  className?: string;
}

export function ImagePicker({
  value,
  onChange,
  label = "Product Image",
  required = false,
  className = "",
}: ImagePickerProps) {
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleFile = useCallback(
    (file: File) => {
      setError(null);
      if (!["image/png", "image/jpeg", "image/gif", "image/webp"].includes(file.type)) {
        setError("Choose a PNG, JPG, GIF, or WEBP image.");
        return;
      }
      if (file.size > 5 * 1024 * 1024) {
        setError("Image must be no larger than 5MB.");
        // 5MB limit
        if (typeof window !== "undefined") {
          import("react-hot-toast").then(({ toast }) =>
            toast.error("Image must be less than 5MB")
          );
        }
        return;
      }

      const reader = new FileReader();
      reader.onerror = () => setError("Unable to read this image. Please select it again.");
      reader.onload = (e) => {
        const result = e.target?.result;
        if (typeof result === "string") {
          onChange(result);
        }
      };
      reader.readAsDataURL(file);
    },
    [onChange]
  );

  const handleFileChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0];
      if (file) handleFile(file);
      // Reset input so same file can be selected again
      if (fileInputRef.current) fileInputRef.current.value = "";
    },
    [handleFile]
  );

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

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(true);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
  }, []);

  const handleRemove = useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();
      onChange(null);
    },
    [onChange]
  );

  return (
    <div className={className}>
      <label className="block text-sm font-medium text-gray-700">
        {label} {required && <span className="text-red-500">*</span>}
      </label>
      <div
        className={`relative mt-1.5 flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed p-4 transition-colors ${
          isDragging
            ? "border-blue-400 bg-blue-50"
            : value
              ? "border-gray-200 bg-gray-50"
              : "border-gray-300 bg-gray-50 hover:border-blue-400 hover:bg-blue-50"
        }`}
        onClick={() => !value && fileInputRef.current?.click()}
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
      >
        <input
          ref={fileInputRef}
          type="file"
          accept="image/png,image/jpeg,image/gif,image/webp"
          onClick={(e) => e.stopPropagation()}
          onChange={handleFileChange}
          className="hidden"
        />

        {value ? (
          <div className="relative w-full">
            <img
              src={value}
              alt="Preview"
              className="mx-auto max-h-40 rounded-lg object-contain"
            />
            <div className="mt-3 flex items-center justify-center gap-2">
              <button
                type="button"
                onClick={() => fileInputRef.current?.click()}
                className="inline-flex items-center gap-1.5 rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-xs font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50"
              >
                <Upload className="h-3.5 w-3.5" />
                Change
              </button>
              <button
                type="button"
                onClick={handleRemove}
                className="inline-flex items-center gap-1.5 rounded-lg border border-red-200 bg-white px-3 py-1.5 text-xs font-medium text-red-600 shadow-sm transition-colors hover:bg-red-50"
              >
                <X className="h-3.5 w-3.5" />
                Remove
              </button>
            </div>
          </div>
        ) : (
          <div className="text-center">
            <Image className="mx-auto h-10 w-10 text-gray-400" />
            <p className="mt-2 text-sm text-gray-600">
              Click to upload or drag and drop
            </p>
            <p className="mt-1 text-xs text-gray-400">
              PNG, JPG, GIF, WEBP up to 5MB
            </p>
          </div>
        )}
      </div>
      {error && <p role="alert" className="mt-1 text-xs text-red-600">{error}</p>}
    </div>
  );
}
