"use client";

import { useState, useRef, type DragEvent, type ChangeEvent } from "react";
import clsx from "clsx";
import { api } from "@/lib/api";

interface ImageUploadProps {
  onUpload: (url: string) => void;
}

const ACCEPTED_TYPES = ["image/jpeg", "image/png", "image/webp"];
const MAX_SIZE = 5 * 1024 * 1024; // 5MB

export function ImageUpload({ onUpload }: ImageUploadProps) {
  const [isDragging, setIsDragging] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const validateFile = (file: File): string | null => {
    if (!ACCEPTED_TYPES.includes(file.type)) {
      return "Only JPG, PNG, and WebP files are allowed.";
    }
    if (file.size > MAX_SIZE) {
      return "File size must be under 5MB.";
    }
    return null;
  };

  const uploadFile = async (file: File) => {
    const validationError = validateFile(file);
    if (validationError) {
      setError(validationError);
      setTimeout(() => setError(null), 3000);
      return;
    }

    setError(null);
    setUploading(true);

    try {
      const response = await api.uploadImage(file);
      onUpload(response.url);
    } catch {
      setError("Upload failed. Please try again.");
      setTimeout(() => setError(null), 3000);
    } finally {
      setUploading(false);
    }
  };

  const handleDragOver = (e: DragEvent) => {
    e.preventDefault();
    setIsDragging(true);
  };

  const handleDragLeave = (e: DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
  };

  const handleDrop = (e: DragEvent) => {
    e.preventDefault();
    setIsDragging(false);

    const file = e.dataTransfer.files[0];
    if (file) {
      uploadFile(file);
    }
  };

  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      uploadFile(file);
    }
  };

  const handleClick = () => {
    inputRef.current?.click();
  };

  return (
    <div
      onClick={handleClick}
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
      className={clsx(
        "border-2 border-dashed p-8 text-center cursor-pointer transition-colors",
        isDragging && "border-black bg-neutral-50",
        error && "border-red-500 animate-shake",
        !isDragging && !error && "border-neutral-300 hover:border-neutral-400"
      )}
    >
      <input
        ref={inputRef}
        type="file"
        accept={ACCEPTED_TYPES.join(",")}
        onChange={handleChange}
        className="hidden"
      />

      {uploading ? (
        <p className="text-sm text-neutral-500">Uploading...</p>
      ) : error ? (
        <p className="text-sm text-red-500">{error}</p>
      ) : (
        <p className="text-sm text-neutral-500">
          Drop an image here or click to upload
        </p>
      )}

      <p className="text-xs text-neutral-400 mt-2">
        JPG, PNG, WebP up to 5MB
      </p>
    </div>
  );
}
