'use client';

import { useState, useRef, useEffect } from 'react';

interface ImageUploadProps {
  currentImageUrl?: string;
  onImageChange: (url: string) => void;
  type: 'wishlist' | 'item';
  label?: string;
  onUploadStateChange?: (isUploading: boolean) => void;
}

export default function ImageUpload({
  currentImageUrl,
  onImageChange,
  type,
  label = 'Image',
  onUploadStateChange,
}: ImageUploadProps) {
  const [isUploading, setIsUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [uploadError, setUploadError] = useState('');
  const [imageUrl, setImageUrl] = useState(currentImageUrl || '');
  const [useUrl, setUseUrl] = useState(!!currentImageUrl);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const pasteAreaRef = useRef<HTMLDivElement>(null);

  const uploadFile = (file: File) => {
    // Client-side validation
    const maxSize = 5 * 1024 * 1024; // 5MB
    const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/gif'];

    if (!allowedTypes.includes(file.type)) {
      setUploadError('Invalid file type. Please upload a JPEG, PNG, WebP, or GIF image.');
      return;
    }

    if (file.size > maxSize) {
      setUploadError('File is too large. Maximum size is 5MB.');
      return;
    }

    setIsUploading(true);
    setUploadProgress(0);
    setUploadError('');
    onUploadStateChange?.(true);

    const formData = new FormData();
    formData.append('file', file);
    formData.append('type', type);

    const xhr = new XMLHttpRequest();

    // Track upload progress
    xhr.upload.addEventListener('progress', (e) => {
      if (e.lengthComputable) {
        const percentComplete = (e.loaded / e.total) * 100;
        setUploadProgress(percentComplete);
      }
    });

    // Handle completion
    xhr.addEventListener('load', () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        try {
          const data = JSON.parse(xhr.responseText);
          setImageUrl(data.url);
          onImageChange(data.url);
          setUploadProgress(100);
        } catch (error) {
          console.error('Failed to parse response:', error);
          setUploadError('Failed to parse server response');
        }
      } else {
        try {
          const data = JSON.parse(xhr.responseText);
          setUploadError(data.error || 'Upload failed');
        } catch {
          setUploadError(`Upload failed with status ${xhr.status}`);
        }
      }
      setIsUploading(false);
      onUploadStateChange?.(false);
    });

    // Handle errors
    xhr.addEventListener('error', () => {
      console.error('Upload error');
      setUploadError('Network error occurred during upload');
      setIsUploading(false);
      onUploadStateChange?.(false);
    });

    // Handle abort
    xhr.addEventListener('abort', () => {
      setUploadError('Upload was cancelled');
      setIsUploading(false);
      onUploadStateChange?.(false);
    });

    xhr.open('POST', '/uploads');
    xhr.send(formData);
  };

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

  const handlePaste = (e: ClipboardEvent) => {
    // Only handle paste if we're in upload mode (not URL mode)
    if (useUrl || imageUrl) return;

    const items = e.clipboardData?.items;
    if (!items) return;

    for (let i = 0; i < items.length; i++) {
      const item = items[i];

      // Check if the item is an image
      if (item.type.indexOf('image') !== -1) {
        e.preventDefault();

        const file = item.getAsFile();
        if (file) {
          uploadFile(file);
        }
        break;
      }
    }
  };

  // Add paste event listener
  useEffect(() => {
    const handlePasteEvent = (e: Event) => handlePaste(e as ClipboardEvent);

    // Listen for paste events on the component's container
    const pasteArea = pasteAreaRef.current;
    if (pasteArea) {
      pasteArea.addEventListener('paste', handlePasteEvent);
    }

    // Also listen globally when in upload mode and no image is set
    if (!useUrl && !imageUrl) {
      document.addEventListener('paste', handlePasteEvent);
    }

    return () => {
      if (pasteArea) {
        pasteArea.removeEventListener('paste', handlePasteEvent);
      }
      document.removeEventListener('paste', handlePasteEvent);
    };
  }, [useUrl, imageUrl]);

  const handleUrlChange = (url: string) => {
    setImageUrl(url);
    onImageChange(url);
  };

  const handleRemoveImage = () => {
    setImageUrl('');
    onImageChange('');
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  };

  return (
    <div ref={pasteAreaRef} className="space-y-3" tabIndex={-1}>
      {label && (
        <label className="flex items-center gap-2 text-base font-medium text-gray-700 dark:text-gray-300">
          {label}
          <div className="group relative inline-block">
            <svg
              className="w-4 h-4 text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 cursor-help transition-colors"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
              aria-label="Upload information"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
              />
            </svg>
            <div className="invisible group-hover:visible opacity-0 group-hover:opacity-100 transition-opacity absolute left-1/2 -translate-x-1/2 bottom-full mb-2 px-3 py-2 bg-gray-900 dark:bg-gray-700 text-white text-xs rounded-lg shadow-lg whitespace-nowrap z-10 pointer-events-none">
              Max 5MB. Allowed: JPEG, PNG, WebP, GIF. Images will be resized to max 800x800px and optimized.
              <div className="absolute top-full left-1/2 -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900 dark:border-t-gray-700"></div>
            </div>
          </div>
        </label>
      )}

      {imageUrl ? (
        /* Image Preview with Remove Button */
        <div className="relative inline-block">
          <img
            src={imageUrl}
            alt="Preview"
            className="w-full h-32 object-cover rounded-lg border-2 border-gray-300 dark:border-gray-600"
            onError={(e) => {
              e.currentTarget.style.display = 'none';
            }}
          />
          <button
            type="button"
            onClick={handleRemoveImage}
            className="absolute -top-2 -right-2 w-6 h-6 bg-red-500 hover:bg-red-600 text-white rounded-full flex items-center justify-center cursor-pointer shadow-lg transition-colors"
            title="Remove image"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>
      ) : (
        <>
          {/* Toggle between URL and File Upload */}
          <div className="grid grid-cols-2 gap-2 mb-3">
            <button
              type="button"
              onClick={() => setUseUrl(true)}
              className={`px-3 py-2 text-base rounded cursor-pointer transition-colors ${
                useUrl
                  ? 'bg-indigo-600 text-white'
                  : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
              }`}
            >
              Use URL
            </button>
            <button
              type="button"
              onClick={() => setUseUrl(false)}
              className={`px-3 py-2 text-base rounded cursor-pointer transition-colors ${
                !useUrl
                  ? 'bg-indigo-600 text-white'
                  : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
              }`}
            >
              Upload File
            </button>
          </div>

          {useUrl ? (
            /* URL Input */
            <div>
              <input
                type="url"
                placeholder="https://example.com/image.jpg"
                className="w-full px-3 py-2 text-base border-2 border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent dark:bg-gray-700 dark:text-white"
                value={imageUrl}
                onChange={(e) => handleUrlChange(e.target.value)}
              />
            </div>
          ) : (
            /* File Upload */
            <div>
              <input
                ref={fileInputRef}
                type="file"
                accept="image/jpeg,image/jpg,image/png,image/webp,image/gif"
                onChange={handleFileUpload}
                className="w-full px-3 py-2 border-2 border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent dark:bg-gray-700 dark:text-white file:mr-4 file:py-2 file:px-4 file:rounded file:border-0 file:text-sm file:font-semibold file:bg-indigo-50 file:text-indigo-700 hover:file:bg-indigo-100"
                disabled={isUploading}
              />
              <p className="mt-1 text-sm text-indigo-600 dark:text-indigo-400 font-medium">
                💡 Tip: You can also paste an image directly (Ctrl+V / Cmd+V)
              </p>
            </div>
          )}

          {/* Error Message */}
          {uploadError && (
            <div className="p-2 bg-red-50 dark:bg-red-900/20 text-red-800 dark:text-red-400 rounded text-base">
              {uploadError}
            </div>
          )}

          {/* Upload Progress Bar */}
          {isUploading && (
            <div className="space-y-2">
              <div className="flex items-center justify-between text-sm text-gray-700 dark:text-gray-300">
                <span>Uploading...</span>
                <span className="font-medium">{Math.round(uploadProgress)}%</span>
              </div>
              <div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2.5 overflow-hidden">
                <div
                  className="bg-indigo-600 h-2.5 rounded-full transition-all duration-300 ease-out"
                  style={{ width: `${uploadProgress}%` }}
                ></div>
              </div>
            </div>
          )}
        </>
      )}
    </div>
  );
}
