import { motion } from 'framer-motion';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Upload, FileText, Eye, X, Plus } from 'lucide-react';

interface DocumentPolicy {
  maxFileSizeMB: number;
  allowedFileTypes: string[];
}

interface DocumentsStepProps {
  documentPolicy: DocumentPolicy;
  isEditing: boolean;
  documents: File[];
  existingDocuments: any[];
  documentsToDelete: string[];
  onDocumentsChange: (documents: File[]) => void;
  onExistingDocumentsChange: (documents: any[]) => void;
  onDocumentsToDeleteChange: (ids: string[]) => void;
  onPreviewDocument: (doc: any, isExisting: boolean) => void;
  onDocumentErrors?: (errors: Array<{ fileName: string; reason: string }>) => void;
  fileInputRef: React.RefObject<HTMLInputElement>;
}

/**
 * Component: DocumentsStep
 * 
 * Purpose: Step 5 - Document upload and management
 * 
 * Features:
 * - File upload with validation
 * - Preview existing documents
 * - Delete documents
 * - Test IDs for testing
 */
export function DocumentsStep({
  documentPolicy,
  isEditing,
  documents,
  existingDocuments,
  documentsToDelete,
  onDocumentsChange,
  onExistingDocumentsChange: _onExistingDocumentsChange,
  onDocumentsToDeleteChange,
  onPreviewDocument,
  onDocumentErrors,
  fileInputRef
}: DocumentsStepProps) {
  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(event.target.files || []);
    if (files.length === 0) return;

    // Validate files
    const maxSizeBytes = documentPolicy.maxFileSizeMB * 1024 * 1024;
    const validationErrors: Array<{ fileName: string; reason: string }> = [];
    const validFiles: File[] = [];

    files.forEach(file => {
      // Check file size
      if (file.size > maxSizeBytes) {
        validationErrors.push({
          fileName: file.name,
          reason: `File size exceeds the maximum allowed size of ${documentPolicy.maxFileSizeMB}MB. Current size: ${(file.size / (1024 * 1024)).toFixed(2)}MB`
        });
        return;
      }

      // Check file extension
      const fileName = file.name.toLowerCase();
      const fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1);
      
      if (!documentPolicy.allowedFileTypes.includes(fileExtension)) {
        validationErrors.push({
          fileName: file.name,
          reason: `File type "${fileExtension}" is not allowed. Allowed types: ${documentPolicy.allowedFileTypes.join(', ')}`
        });
        return;
      }

      validFiles.push(file);
    });

    // Update parent with valid files
    if (validFiles.length > 0) {
      onDocumentsChange([...documents, ...validFiles]);
    }

    // Show errors if any
    if (validationErrors.length > 0 && onDocumentErrors) {
      onDocumentErrors(validationErrors);
    }

    // Reset file input
    if (event.target) {
      event.target.value = '';
    }
  };

  const handleRemove = (index: number) => {
    const newDocs = documents.filter((_, i) => i !== index);
    onDocumentsChange(newDocs);
  };

  const handleDeleteExisting = (docId: string) => {
    onDocumentsToDeleteChange([...documentsToDelete, docId]);
  };

  const canPreview = (doc: any, isExisting: boolean = false): boolean => {
    if (isExisting) {
      const type = (doc.fileType || doc.file_type || '').toLowerCase();
      const name = (doc.originalFileName || doc.fileName || '').toLowerCase();
      return type.includes('image') || type.includes('pdf') ||
             name.endsWith('.jpg') || name.endsWith('.jpeg') ||
             name.endsWith('.png') || name.endsWith('.gif') ||
             name.endsWith('.pdf');
    } else {
      const type = (doc.type || '').toLowerCase();
      const name = (doc.name || '').toLowerCase();
      return type.includes('image') || type.includes('pdf') ||
             name.endsWith('.jpg') || name.endsWith('.jpeg') ||
             name.endsWith('.png') || name.endsWith('.gif') ||
             name.endsWith('.pdf');
    }
  };

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -20 }}
      className="space-y-6"
      data-testid="documents-step"
    >
      <div className="text-center mb-8" data-testid="documents-header">
        <div className="w-16 h-16 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-2xl flex items-center justify-center mx-auto mb-4">
          <Upload className="w-8 h-8 text-white" />
        </div>
        <h2 className="text-2xl font-bold text-gray-900 mb-2" data-testid="documents-title">
          Documents & Attachments
        </h2>
        <p className="text-gray-600" data-testid="documents-description">
          Upload supporting documents, files, and any additional materials for your request.
        </p>
      </div>

      <div className="max-w-2xl mx-auto space-y-6" data-testid="documents-content">
        <Card data-testid="documents-upload-card">
          <CardHeader>
            <CardTitle className="flex items-center gap-2" data-testid="documents-upload-title">
              <FileText className="w-5 h-5" />
              File Upload
            </CardTitle>
            <CardDescription>
              Attach supporting documents. Max {documentPolicy.maxFileSizeMB}MB per file. Allowed types: {documentPolicy.allowedFileTypes.join(', ')}
            </CardDescription>
          </CardHeader>
          <CardContent>
            <div className="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-gray-400 transition-colors" data-testid="documents-upload-area">
              <Upload className="h-12 w-12 mx-auto mb-4 text-gray-400" />
              <h3 className="text-lg font-semibold text-gray-900 mb-2">Upload Files</h3>
              <p className="text-gray-600 mb-4">
                Drag and drop files here, or click to browse
              </p>
              <input
                type="file"
                multiple
                accept={documentPolicy.allowedFileTypes.map(ext => `.${ext}`).join(',')}
                onChange={handleFileChange}
                className="hidden"
                id="file-upload"
                ref={fileInputRef}
                data-testid="documents-file-input"
              />
              <Button 
                variant="outline" 
                size="lg" 
                type="button" 
                onClick={() => fileInputRef.current?.click()}
                data-testid="documents-browse-button"
              >
                <Plus className="w-4 h-4 mr-2" />
                Browse Files
              </Button>
              <p className="text-xs text-gray-500 mt-2">
                Supported formats: {documentPolicy.allowedFileTypes.map(ext => ext.toUpperCase()).join(', ')} (Max {documentPolicy.maxFileSizeMB}MB per file)
              </p>
            </div>
          </CardContent>
        </Card>

        {/* Existing Documents */}
        {isEditing && existingDocuments.length > 0 && (
          <Card data-testid="documents-existing-card">
            <CardHeader>
              <CardTitle className="flex items-center justify-between" data-testid="documents-existing-title">
                <span>Existing Documents</span>
                <Badge variant="secondary" data-testid="documents-existing-count">
                  {existingDocuments.filter(d => !documentsToDelete.includes(d.documentId || d.document_id || '')).length} file{existingDocuments.filter(d => !documentsToDelete.includes(d.documentId || d.document_id || '')).length !== 1 ? 's' : ''}
                </Badge>
              </CardTitle>
            </CardHeader>
            <CardContent>
              <div className="space-y-3" data-testid="documents-existing-list">
                {existingDocuments.map((doc: any) => {
                  const docId = doc.documentId || doc.document_id || '';
                  const isDeleted = documentsToDelete.includes(docId);
                  if (isDeleted) return null;
                  
                  return (
                    <div key={docId} className="flex items-center justify-between p-4 rounded-lg border bg-gray-50" data-testid={`documents-existing-${docId}`}>
                      <div className="flex items-center gap-3">
                        <div className="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center">
                          <FileText className="h-5 w-5 text-blue-600" />
                        </div>
                        <div>
                          <p className="font-medium text-gray-900">{doc.originalFileName || doc.fileName || 'Document'}</p>
                          <div className="flex items-center gap-3 text-sm text-gray-600">
                            <span>{doc.fileSize ? (Number(doc.fileSize) / (1024 * 1024)).toFixed(2) + ' MB' : 'Unknown size'}</span>
                          </div>
                        </div>
                      </div>
                      <div className="flex items-center gap-2">
                        {canPreview(doc, true) && (
                          <Button 
                            variant="ghost" 
                            size="sm" 
                            onClick={() => onPreviewDocument(doc, true)}
                            data-testid={`documents-existing-${docId}-preview`}
                          >
                            <Eye className="h-4 w-4" />
                          </Button>
                        )}
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => handleDeleteExisting(docId)}
                          data-testid={`documents-existing-${docId}-delete`}
                        >
                          <X className="h-4 w-4 text-red-600" />
                        </Button>
                      </div>
                    </div>
                  );
                })}
              </div>
            </CardContent>
          </Card>
        )}

        {/* New Documents */}
        {documents.length > 0 && (
          <Card data-testid="documents-new-card">
            <CardHeader>
              <CardTitle className="flex items-center justify-between" data-testid="documents-new-title">
                <span>New Files to Upload</span>
                <Badge variant="secondary" data-testid="documents-new-count">
                  {documents.length} file{documents.length !== 1 ? 's' : ''}
                </Badge>
              </CardTitle>
            </CardHeader>
            <CardContent>
              <div className="space-y-3" data-testid="documents-new-list">
                {documents.map((file, index) => (
                  <div key={index} className="flex items-center justify-between p-4 bg-gray-50 rounded-lg border" data-testid={`documents-new-${index}`}>
                    <div className="flex items-center gap-3">
                      <div className="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center">
                        <FileText className="h-5 w-5 text-blue-600" />
                      </div>
                      <div>
                        <p className="font-medium text-gray-900">{file.name}</p>
                        <div className="flex items-center gap-3 text-sm text-gray-600">
                          <span>{(file.size / (1024 * 1024)).toFixed(2)} MB</span>
                        </div>
                      </div>
                    </div>
                    <div className="flex items-center gap-2">
                      {canPreview(file, false) && (
                        <Button 
                          variant="ghost" 
                          size="sm" 
                          onClick={() => onPreviewDocument(file, false)}
                          data-testid={`documents-new-${index}-preview`}
                        >
                          <Eye className="h-4 w-4" />
                        </Button>
                      )}
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => handleRemove(index)}
                        data-testid={`documents-new-${index}-remove`}
                      >
                        <X className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                ))}
              </div>
            </CardContent>
          </Card>
        )}
      </div>
    </motion.div>
  );
}

