import React, { useState, useEffect, useRef } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast';
import { useAuth } from '@/contexts/AuthContext';
import { Plus, Trash2, FileText, UploadCloud, X, Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';

function DocumentDialog({ open, onOpenChange, onSuccess }) {
  const { toast } = useToast();
  const { user } = useAuth();
  const [associations, setAssociations] = useState([]);
  
  const [isDragging, setIsDragging] = useState(false);
  const fileInputRef = useRef(null);
  
  const [files, setFiles] = useState([
    { id: Date.now(), title: '', description: '', file_url: '', fileObject: null }
  ]);
  
  const [commonData, setCommonData] = useState({
    association_id: '',
    category: '',
  });
  
  const [loading, setLoading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);

  useEffect(() => {
    const fetchData = async () => {
      const { data } = await supabase.from('associations').select('id, name').eq('status', 'active').order('name');
      setAssociations(data || []);
    };
    
    if (open) {
      fetchData();
      setFiles([{ id: Date.now(), title: '', description: '', file_url: '', fileObject: null }]);
      setCommonData({ association_id: '', category: '' });
      setUploadProgress(0);
    }
  }, [open]);

  const handleDragOver = (e) => { e.preventDefault(); setIsDragging(true); };
  const handleDragLeave = (e) => { e.preventDefault(); setIsDragging(false); };

  const processDroppedFiles = (droppedFiles) => {
    const newFiles = Array.from(droppedFiles).map(file => ({
      id: Math.random().toString(36).substr(2, 9),
      title: file.name,
      description: '',
      file_url: '',
      fileObject: file
    }));

    if (files.length === 1 && !files[0].title && !files[0].file_url && !files[0].fileObject) {
      setFiles(newFiles);
    } else {
      setFiles(prev => [...prev, ...newFiles]);
    }
  };

  const handleDrop = (e) => {
    e.preventDefault();
    setIsDragging(false);
    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
      processDroppedFiles(e.dataTransfer.files);
    }
  };

  const handleFileInputChange = (e) => {
    if (e.target.files && e.target.files.length > 0) {
      processDroppedFiles(e.target.files);
    }
    if (fileInputRef.current) fileInputRef.current.value = '';
  };

  const handleAddEmptyRow = () => {
    setFiles([...files, { id: Date.now(), title: '', description: '', file_url: '', fileObject: null }]);
  };

  const handleRemoveFile = (id) => {
    if (files.length > 1) {
      setFiles(files.filter(f => f.id !== id));
    } else {
      setFiles([{ id: Date.now(), title: '', description: '', file_url: '', fileObject: null }]);
    }
  };

  const handleFileChange = (id, field, value) => {
    setFiles(files.map(f => f.id === id ? { ...f, [field]: value } : f));
  };

  const uploadFileToStorage = async (fileObj) => {
    if (!user) throw new Error("User not authenticated");
    const fileExt = fileObj.name.split('.').pop();
    const fileName = `${Date.now()}-${Math.random().toString(36).substring(2)}.${fileExt}`;
    const filePath = `${user.id}/${fileName}`;

    const { error: uploadError } = await supabase.storage
      .from('files')
      .upload(filePath, fileObj);

    if (uploadError) throw uploadError;

    const { data: { publicUrl } } = supabase.storage
      .from('files')
      .getPublicUrl(filePath);

    return publicUrl;
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    setUploadProgress(0);

    if (!user) {
      toast({ variant: "destructive", title: "Error", description: "You must be logged in to upload documents." });
      setLoading(false);
      return;
    }

    if (!commonData.association_id) {
      toast({ variant: "destructive", title: "Error", description: "Please select an association." });
      setLoading(false);
      return;
    }

    const validFiles = files.filter(f => f.title.trim() !== '');
    if (validFiles.length === 0) {
      toast({ variant: "destructive", title: "Error", description: "Please add at least one document with a title." });
      setLoading(false);
      return;
    }

    try {
      const documentsToInsert = [];
      let completedCount = 0;

      for (const file of validFiles) {
        let finalUrl = file.file_url;
        if (file.fileObject) {
          finalUrl = await uploadFileToStorage(file.fileObject);
        }

        documentsToInsert.push({
          title: file.title,
          file_url: finalUrl,
          file_name: file.fileObject?.name || file.title,
          file_size: file.fileObject?.size || null,
          association_id: commonData.association_id,
          category: commonData.category || 'general',
          uploaded_by: user.id,
        });

        completedCount++;
        setUploadProgress(Math.round((completedCount / validFiles.length) * 100));
      }

      const { error } = await supabase.from('documents').insert(documentsToInsert);
      if (error) throw error;

      toast({
        title: "Success",
        description: `Successfully uploaded ${validFiles.length} document(s).`,
      });
      onSuccess();
      onOpenChange(false);
    } catch (error) {
      console.error('Upload error:', error);
      toast({
        variant: "destructive",
        title: "Upload Failed",
        description: error.message || "An error occurred while uploading documents.",
      });
    } finally {
      setLoading(false);
      setUploadProgress(0);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[700px] max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="text-xl">Upload Documents</DialogTitle>
        </DialogHeader>
        <form onSubmit={handleSubmit} className="space-y-6">
          
          <div className="grid grid-cols-2 gap-4 p-4 bg-muted rounded-lg border">
              <div>
                <Label htmlFor="association_id">Association *</Label>
                <select
                  id="association_id"
                  value={commonData.association_id}
                  onChange={(e) => setCommonData({ ...commonData, association_id: e.target.value })}
                  required
                  className="w-full mt-1.5 px-3 py-2 text-sm border rounded-md focus:ring-2 focus:ring-primary bg-background"
                >
                  <option value="">Select an association</option>
                  {associations.map((a) => (
                    <option key={a.id} value={a.id}>{a.name}</option>
                  ))}
                </select>
              </div>
              <div>
                <Label htmlFor="category">Category (Optional)</Label>
                <select
                  id="category"
                  value={commonData.category}
                  onChange={(e) => setCommonData({ ...commonData, category: e.target.value })}
                  className="w-full mt-1.5 px-3 py-2 text-sm border rounded-md focus:ring-2 focus:ring-primary bg-background"
                >
                  <option value="">General</option>
                  <option value="financial">Financial</option>
                  <option value="legal">Legal</option>
                  <option value="insurance">Insurance</option>
                  <option value="meeting_minutes">Meeting Minutes</option>
                </select>
              </div>
          </div>

          <div 
            className={cn(
              "border-2 border-dashed rounded-xl p-8 transition-colors text-center cursor-pointer",
              isDragging 
                ? "border-primary bg-primary/5" 
                : "border-border hover:border-primary/50 bg-background"
            )}
            onDragOver={handleDragOver}
            onDragLeave={handleDragLeave}
            onDrop={handleDrop}
            onClick={() => fileInputRef.current?.click()}
          >
            <input 
              type="file" 
              ref={fileInputRef}
              className="hidden" 
              multiple 
              onChange={handleFileInputChange}
            />
            <div className="flex flex-col items-center gap-2">
              <div className="p-3 bg-primary/10 text-primary rounded-full">
                <UploadCloud className="w-6 h-6" />
              </div>
              <div className="text-sm font-medium">
                Click to upload or drag and drop
              </div>
              <p className="text-xs text-muted-foreground">
                PDF, DOCX, XLSX, Images (max 10MB)
              </p>
            </div>
          </div>

          <div className="space-y-3">
              <div className="flex items-center justify-between">
                  <Label className="text-base font-semibold">Files to Upload ({files.length})</Label>
                  <Button type="button" variant="ghost" size="sm" onClick={handleAddEmptyRow} className="text-xs">
                      <Plus className="w-3 h-3 mr-1" /> Add Manual Link
                  </Button>
              </div>

              <div className="max-h-[300px] overflow-y-auto space-y-3 pr-2">
                {files.map((file) => (
                    <div key={file.id} className="relative p-4 bg-background border rounded-lg shadow-sm group">
                        <Button 
                            type="button" 
                            variant="ghost" 
                            size="icon" 
                            onClick={() => handleRemoveFile(file.id)}
                            className="absolute top-2 right-2 h-6 w-6 text-muted-foreground hover:text-destructive opacity-0 group-hover:opacity-100 transition-opacity"
                        >
                            <X className="w-4 h-4" />
                        </Button>
                        
                        <div className="flex gap-4">
                            <div className="flex-shrink-0 mt-1">
                                <div className={cn("p-2 rounded-lg", file.fileObject ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground")}>
                                    <FileText className="w-5 h-5" />
                                </div>
                            </div>
                            
                            <div className="flex-1 grid grid-cols-1 gap-3">
                                <input
                                    type="text"
                                    placeholder="Document Title"
                                    value={file.title}
                                    onChange={(e) => handleFileChange(file.id, 'title', e.target.value)}
                                    className="w-full px-0 py-1 text-sm font-medium border-0 border-b border-transparent hover:border-border focus:border-primary focus:ring-0 bg-transparent placeholder:text-muted-foreground transition-colors"
                                />
                                
                                {file.fileObject ? (
                                    <div className="text-xs text-muted-foreground flex items-center">
                                        <span className="bg-muted px-2 py-0.5 rounded mr-2">
                                            {(file.fileObject.size / 1024 / 1024).toFixed(2)} MB
                                        </span>
                                        Ready to upload
                                    </div>
                                ) : (
                                    <input
                                        type="url"
                                        placeholder="External File URL (https://...)"
                                        value={file.file_url}
                                        onChange={(e) => handleFileChange(file.id, 'file_url', e.target.value)}
                                        className="w-full px-2 py-1.5 text-xs border rounded bg-muted focus:bg-background focus:border-primary focus:outline-none"
                                    />
                                )}

                                <input
                                    type="text"
                                    placeholder="Description (optional)"
                                    value={file.description}
                                    onChange={(e) => handleFileChange(file.id, 'description', e.target.value)}
                                    className="w-full px-2 py-1.5 text-xs border rounded focus:border-primary focus:outline-none"
                                />
                            </div>
                        </div>
                    </div>
                ))}
              </div>
          </div>

          <div className="flex justify-end items-center gap-3 pt-4 border-t">
            <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={loading}>
              Cancel
            </Button>
            <Button type="submit" disabled={loading} className="min-w-[140px]">
              {loading ? (
                <>
                  <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                  {uploadProgress > 0 ? `${uploadProgress}%` : 'Processing...'}
                </>
              ) : (
                `Upload ${files.length} File${files.length !== 1 ? 's' : ''}`
              )}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export default DocumentDialog;
