/**
 * Image Uploader Component
 * Agent 3: File Upload & Storage System
 *
 * Drag & drop image upload with preview and progress
 */

import React, { useState, useCallback, useRef } from 'react';
import type { FileCategory } from '../../lib/storage/types';

interface UploadedFile {
  id: string;
  url: string;
  thumbnailUrl?: string;
  width?: number;
  height?: number;
  size: number;
}

interface ImageUploaderProps {
  category?: FileCategory;
  plantId?: string;
  farmId?: string;
  userId?: string;
  onUpload?: (file: UploadedFile) => void;
  onError?: (error: string) => void;
  maxFiles?: number;
  accept?: string;
  className?: string;
}

interface UploadState {
  isUploading: boolean;
  progress: number;
  error?: string;
  preview?: string;
}

export function ImageUploader({
  category = 'plant-photo',
  plantId,
  farmId,
  userId,
  onUpload,
  onError,
  maxFiles = 1,
  accept = 'image/*',
  className = '',
}: ImageUploaderProps) {
  const [uploadState, setUploadState] = useState<UploadState>({
    isUploading: false,
    progress: 0,
  });
  const [isDragging, setIsDragging] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

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

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

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

  const uploadFile = async (file: File) => {
    // Create preview
    const reader = new FileReader();
    reader.onload = (e) => {
      setUploadState((prev) => ({
        ...prev,
        preview: e.target?.result as string,
      }));
    };
    reader.readAsDataURL(file);

    // Start upload
    setUploadState((prev) => ({
      ...prev,
      isUploading: true,
      progress: 0,
      error: undefined,
    }));

    const formData = new FormData();
    formData.append('file', file);
    formData.append('category', category);
    if (plantId) formData.append('plantId', plantId);
    if (farmId) formData.append('farmId', farmId);
    if (userId) formData.append('userId', userId);

    try {
      const response = await fetch('/api/upload/image', {
        method: 'POST',
        body: formData,
      });

      const data = await response.json();

      if (!data.success) {
        throw new Error(data.error || 'Upload failed');
      }

      setUploadState({
        isUploading: false,
        progress: 100,
        preview: data.file.thumbnailUrl || data.file.url,
      });

      onUpload?.(data.file);
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Upload failed';
      setUploadState((prev) => ({
        ...prev,
        isUploading: false,
        error: message,
      }));
      onError?.(message);
    }
  };

  const handleDrop = useCallback(
    async (e: React.DragEvent) => {
      e.preventDefault();
      e.stopPropagation();
      setIsDragging(false);

      const files = Array.from(e.dataTransfer.files).slice(0, maxFiles);
      if (files.length > 0) {
        await uploadFile(files[0]);
      }
    },
    [maxFiles]
  );

  const handleFileChange = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      const files = Array.from(e.target.files || []).slice(0, maxFiles);
      if (files.length > 0) {
        await uploadFile(files[0]);
      }
    },
    [maxFiles]
  );

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

  const handleRemove = () => {
    setUploadState({
      isUploading: false,
      progress: 0,
      preview: undefined,
      error: undefined,
    });
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  };

  return (
    <div className={`relative ${className}`}>
      <input
        ref={fileInputRef}
        type="file"
        accept={accept}
        onChange={handleFileChange}
        className="hidden"
      />

      {uploadState.preview ? (
        <div className="relative rounded-lg overflow-hidden border-2 border-green-200">
          <img
            src={uploadState.preview}
            alt="Uploaded preview"
            className="w-full h-48 object-cover"
          />
          <button
            onClick={handleRemove}
            className="absolute top-2 right-2 bg-red-500 text-white rounded-full p-1 hover:bg-red-600 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>
      ) : (
        <div
          onClick={handleClick}
          onDragEnter={handleDragEnter}
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          onDrop={handleDrop}
          className={`
            border-2 border-dashed rounded-lg p-8 text-center cursor-pointer
            transition-colors duration-200
            ${isDragging
              ? 'border-green-500 bg-green-50'
              : 'border-gray-300 hover:border-green-400 hover:bg-gray-50'
            }
            ${uploadState.isUploading ? 'pointer-events-none opacity-50' : ''}
          `}
        >
          <svg
            className="mx-auto h-12 w-12 text-gray-400"
            stroke="currentColor"
            fill="none"
            viewBox="0 0 48 48"
          >
            <path
              d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
              strokeWidth={2}
              strokeLinecap="round"
              strokeLinejoin="round"
            />
          </svg>
          <p className="mt-2 text-sm text-gray-600">
            <span className="text-green-600 font-medium">Click to upload</span>
            {' '}or drag and drop
          </p>
          <p className="mt-1 text-xs text-gray-500">
            PNG, JPG, GIF, WEBP up to 5MB
          </p>
        </div>
      )}

      {uploadState.isUploading && (
        <div className="mt-2">
          <div className="bg-gray-200 rounded-full h-2">
            <div
              className="bg-green-500 h-2 rounded-full transition-all duration-300"
              style={{ width: `${uploadState.progress}%` }}
            />
          </div>
          <p className="text-xs text-gray-500 mt-1 text-center">Uploading...</p>
        </div>
      )}

      {uploadState.error && (
        <p className="mt-2 text-sm text-red-500 text-center">{uploadState.error}</p>
      )}
    </div>
  );
}

export default ImageUploader;
