'use client';

import { useState, useCallback } from 'react';
import { Upload, File as FileIcon, X, Eye } from 'lucide-react';
import { Button } from './ui/button';
import { Card } from './ui/card';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from './ui/dialog';

interface UploadedFile {
  file: File;
  text?: string;
}

interface FileUploadProps {
  onFilesUploaded: (files: File[]) => void;
  onTextExtracted?: (fileName: string, text: string) => void;
}

export function FileUpload({ onFilesUploaded, onTextExtracted }: FileUploadProps) {
  const [files, setFiles] = useState<UploadedFile[]>([]);
  const [isDragging, setIsDragging] = useState(false);
  const [selectedFile, setSelectedFile] = useState<UploadedFile | null>(null);
  const [isLoading, setIsLoading] = useState<{ [key: string]: boolean }>({});

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

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

  const processFile = async (file: File) => {
    setIsLoading(prev => ({ ...prev, [file.name]: true }));
    
    try {
      const formData = new FormData();
      formData.append('file', file);

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

      if (!response.ok) {
        throw new Error('Failed to extract text');
      }

      const data = await response.json();
      if (onTextExtracted) {
        onTextExtracted(file.name, data.text);
      }
      return data.text;
    } catch (error) {
      console.error('Error extracting text:', error);
      return undefined;
    } finally {
      setIsLoading(prev => ({ ...prev, [file.name]: false }));
    }
  };

  const handleDrop = useCallback(async (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    
    const droppedFiles = Array.from(e.dataTransfer.files).filter(
      file => file.type === 'application/pdf'
    );
    
    if (droppedFiles.length > 0) {
      const newFiles = droppedFiles.map(file => ({ file }));
      setFiles(prev => [...prev, ...newFiles]);
      onFilesUploaded(droppedFiles);

      // Process each file
      for (const file of droppedFiles) {
        const text = await processFile(file);
        setFiles(prev => 
          prev.map(f => 
            f.file.name === file.name ? { ...f, text } : f
          )
        );
      }
    }
  }, [onFilesUploaded]);

  const handleFileInput = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      const selectedFiles = Array.from(e.target.files).filter(
        file => file.type === 'application/pdf'
      );
      
      if (selectedFiles.length > 0) {
        const newFiles = selectedFiles.map(file => ({ file }));
        setFiles(prev => [...prev, ...newFiles]);
        onFilesUploaded(selectedFiles);

        // Process each file
        for (const file of selectedFiles) {
          const text = await processFile(file);
          setFiles(prev => 
            prev.map(f => 
              f.file.name === file.name ? { ...f, text } : f
            )
          );
        }
      }
    }
  }, [onFilesUploaded]);

  const removeFile = useCallback((index: number) => {
    setFiles(prev => prev.filter((_, i) => i !== index));
  }, []);

  return (
    <div className="w-full space-y-4">
      <div
        className={`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer ${
          isDragging ? 'border-primary bg-primary/10' : 'border-gray-300'
        }`}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        onClick={() => document.getElementById('file-upload')?.click()}
      >
        <Upload className="mx-auto h-12 w-12 text-gray-400" />
        <div className="mt-4">
          <span className="text-primary hover:text-primary/80">
            Click to upload
          </span>
          <span className="text-gray-500"> or drag and drop</span>
          <input
            id="file-upload"
            type="file"
            className="hidden"
            multiple
            accept=".pdf"
            onChange={handleFileInput}
          />
        </div>
        <p className="text-sm text-gray-500 mt-2">PDF files only</p>
      </div>

      {files.length > 0 && (
        <div className="space-y-2">
          {files.map((uploadedFile, index) => (
            <Card key={index} className="p-4 flex items-center justify-between">
              <div className="flex items-center space-x-4">
                <FileIcon className="h-6 w-6 text-gray-400" />
                <span className="text-sm">{uploadedFile.file.name}</span>
                {isLoading[uploadedFile.file.name] && (
                  <span className="text-sm text-gray-500">Processing...</span>
                )}
              </div>
              <div className="flex items-center space-x-2">
                {uploadedFile.text && (
                  <Button
                    variant="outline"
                    size="icon"
                    onClick={() => setSelectedFile(uploadedFile)}
                  >
                    <Eye className="h-4 w-4" />
                  </Button>
                )}
                <Button
                  variant="ghost"
                  size="icon"
                  onClick={() => removeFile(index)}
                >
                  <X className="h-4 w-4" />
                </Button>
              </div>
            </Card>
          ))}
        </div>
      )}

      <Dialog open={!!selectedFile} onOpenChange={() => setSelectedFile(null)}>
        <DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{selectedFile?.file.name}</DialogTitle>
          </DialogHeader>
          <div className="mt-4 whitespace-pre-wrap font-mono text-sm">
            {selectedFile?.text}
          </div>
        </DialogContent>
      </Dialog>
    </div>
  );
}
