'use client';

import React, { useState, useRef, useCallback } from 'react';
import { 
  Upload, 
  X, 
  Play, 
  Pause, 
  Volume2, 
  VolumeX, 
  Eye, 
  Download, 
  Trash2, 
  Image, 
  Video, 
  Music, 
  File,
  CheckCircle,
  AlertCircle,
  Loader2,
  FolderOpen,
  Search,
  Filter
} from 'lucide-react';

export interface MultimediaFile {
  id: string;
  name: string;
  type: 'image' | 'video' | 'audio' | 'document';
  url: string;
  size: number;
  uploadedAt: Date;
  thumbnail?: string;
  duration?: number; // for video/audio in seconds
  dimensions?: { width: number; height: number }; // for images/videos
}

interface MultimediaManagerProps {
  files: MultimediaFile[];
  onFileUpload: (files: File[]) => Promise<MultimediaFile[]>;
  onFileDelete: (fileId: string) => Promise<void>;
  onFileSelect?: (file: MultimediaFile) => void;
  selectedFiles?: string[];
  maxFileSize?: number; // in MB
  allowedTypes?: string[];
  multiple?: boolean;
  showPreview?: boolean;
  className?: string;
}

const ALLOWED_TYPES = {
  image: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
  video: ['video/mp4', 'video/webm', 'video/ogg'],
  audio: ['audio/mp3', 'audio/wav', 'audio/ogg', 'audio/m4a'],
  document: ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']
};

export const MultimediaManager: React.FC<MultimediaManagerProps> = ({
  files,
  onFileUpload,
  onFileDelete,
  onFileSelect,
  selectedFiles = [],
  maxFileSize = 10, // 10MB default
  allowedTypes = Object.values(ALLOWED_TYPES).flat(),
  multiple = true,
  showPreview = true,
  className = ''
}) => {
  const [isDragging, setIsDragging] = useState(false);
  const [uploadingFiles, setUploadingFiles] = useState<string[]>([]);
  const [searchTerm, setSearchTerm] = useState('');
  const [filterType, setFilterType] = useState<'all' | 'image' | 'video' | 'audio' | 'document'>('all');
  const [previewFile, setPreviewFile] = useState<MultimediaFile | null>(null);
  const [playingAudio, setPlayingAudio] = useState<string | null>(null);
  const [playingVideo, setPlayingVideo] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const audioRef = useRef<HTMLAudioElement>(null);

  const formatFileSize = (bytes: number): string => {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  };

  const formatDuration = (seconds: number): string => {
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  const getFileType = (mimeType: string): MultimediaFile['type'] => {
    if (ALLOWED_TYPES.image.includes(mimeType)) return 'image';
    if (ALLOWED_TYPES.video.includes(mimeType)) return 'video';
    if (ALLOWED_TYPES.audio.includes(mimeType)) return 'audio';
    return 'document';
  };

  const getFileIcon = (type: MultimediaFile['type']) => {
    switch (type) {
      case 'image': return Image;
      case 'video': return Video;
      case 'audio': return Music;
      default: return File;
    }
  };

  const validateFile = (file: File): string | null => {
    if (!allowedTypes.includes(file.type)) {
      return `File type ${file.type} is not allowed`;
    }
    if (file.size > maxFileSize * 1024 * 1024) {
      return `File size exceeds ${maxFileSize}MB limit`;
    }
    return null;
  };

  const handleFileSelect = useCallback(async (selectedFiles: FileList | File[]) => {
    const filesArray = Array.from(selectedFiles);
    const validFiles: File[] = [];
    const errors: string[] = [];

    filesArray.forEach(file => {
      const error = validateFile(file);
      if (error) {
        errors.push(`${file.name}: ${error}`);
      } else {
        validFiles.push(file);
      }
    });

    if (errors.length > 0) {
      alert('Some files were rejected:\n' + errors.join('\n'));
    }

    if (validFiles.length > 0) {
      const fileIds = validFiles.map(f => f.name);
      setUploadingFiles(prev => [...prev, ...fileIds]);

      try {
        await onFileUpload(validFiles);
      } catch (error) {
        console.error('Upload failed:', error);
        alert('Upload failed. Please try again.');
      } finally {
        setUploadingFiles(prev => prev.filter(id => !fileIds.includes(id)));
      }
    }
  }, [onFileUpload, allowedTypes, maxFileSize]);

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

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

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    const files = e.dataTransfer.files;
    if (files.length > 0) {
      handleFileSelect(files);
    }
  }, [handleFileSelect]);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      handleFileSelect(e.target.files);
    }
  };

  const handleAudioPlay = (fileId: string, url: string) => {
    if (playingAudio === fileId) {
      audioRef.current?.pause();
      setPlayingAudio(null);
    } else {
      if (audioRef.current) {
        audioRef.current.src = url;
        audioRef.current.play();
        setPlayingAudio(fileId);
      }
    }
  };

  const handleVideoPlay = (fileId: string) => {
    setPlayingVideo(playingVideo === fileId ? null : fileId);
  };

  const filteredFiles = files.filter(file => {
    const matchesSearch = file.name.toLowerCase().includes(searchTerm.toLowerCase());
    const matchesType = filterType === 'all' || file.type === filterType;
    return matchesSearch && matchesType;
  });

  return (
    <div className={`bg-white rounded-lg border ${className}`}>
      {/* Header */}
      <div className="p-4 border-b">
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-lg font-medium text-gray-900">Multimedia Manager</h3>
          <button
            onClick={() => fileInputRef.current?.click()}
            className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
          >
            <Upload className="w-4 h-4" />
            Upload Files
          </button>
        </div>

        {/* Search and Filter */}
        <div className="flex gap-4">
          <div className="flex-1 relative">
            <Search className="w-4 h-4 absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" />
            <input
              type="text"
              placeholder="Search files..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>
          <select
            value={filterType}
            onChange={(e) => setFilterType(e.target.value as any)}
            className="px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
          >
            <option value="all">All Types</option>
            <option value="image">Images</option>
            <option value="video">Videos</option>
            <option value="audio">Audio</option>
            <option value="document">Documents</option>
          </select>
        </div>
      </div>

      {/* Upload Area */}
      <div
        className={`p-6 border-2 border-dashed transition-colors ${
          isDragging 
            ? 'border-blue-500 bg-blue-50' 
            : 'border-gray-300 hover:border-gray-400'
        }`}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
      >
        <div className="text-center">
          <FolderOpen className="w-12 h-12 text-gray-400 mx-auto mb-3" />
          <p className="text-gray-600 mb-2">
            Drag and drop files here, or{' '}
            <button
              onClick={() => fileInputRef.current?.click()}
              className="text-blue-600 hover:text-blue-700 font-medium"
            >
              browse
            </button>
          </p>
          <p className="text-sm text-gray-500">
            Max file size: {maxFileSize}MB. Supported: Images, Videos, Audio, Documents
          </p>
        </div>
      </div>

      {/* Files Grid */}
      <div className="p-4">
        {filteredFiles.length === 0 ? (
          <div className="text-center py-8 text-gray-500">
            {files.length === 0 ? 'No files uploaded yet' : 'No files match your search'}
          </div>
        ) : (
          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
            {filteredFiles.map((file) => {
              const Icon = getFileIcon(file.type);
              const isSelected = selectedFiles.includes(file.id);
              const isUploading = uploadingFiles.includes(file.name);

              return (
                <div
                  key={file.id}
                  className={`relative group border rounded-lg overflow-hidden transition-all cursor-pointer ${
                    isSelected 
                      ? 'border-blue-500 bg-blue-50' 
                      : 'border-gray-200 hover:border-gray-300'
                  }`}
                  onClick={() => onFileSelect?.(file)}
                >
                  {/* File Preview */}
                  <div className="aspect-square bg-gray-100 flex items-center justify-center relative">
                    {file.type === 'image' ? (
                      <img
                        src={file.url}
                        alt={file.name}
                        className="w-full h-full object-cover"
                      />
                    ) : file.type === 'video' ? (
                      <div className="relative w-full h-full">
                        {playingVideo === file.id ? (
                          <video
                            src={file.url}
                            controls
                            autoPlay
                            className="w-full h-full object-cover"
                          />
                        ) : (
                          <div className="w-full h-full bg-gray-200 flex items-center justify-center">
                            <Video className="w-8 h-8 text-gray-400" />
                          </div>
                        )}
                        <button
                          onClick={(e) => {
                            e.stopPropagation();
                            handleVideoPlay(file.id);
                          }}
                          className="absolute inset-0 flex items-center justify-center bg-black bg-opacity-50 opacity-0 group-hover:opacity-100 transition-opacity"
                        >
                          {playingVideo === file.id ? (
                            <Pause className="w-8 h-8 text-white" />
                          ) : (
                            <Play className="w-8 h-8 text-white" />
                          )}
                        </button>
                      </div>
                    ) : (
                      <Icon className="w-8 h-8 text-gray-400" />
                    )}

                    {/* Loading Overlay */}
                    {isUploading && (
                      <div className="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center">
                        <Loader2 className="w-6 h-6 text-white animate-spin" />
                      </div>
                    )}

                    {/* Selection Indicator */}
                    {isSelected && (
                      <div className="absolute top-2 right-2">
                        <CheckCircle className="w-5 h-5 text-blue-600 bg-white rounded-full" />
                      </div>
                    )}
                  </div>

                  {/* File Info */}
                  <div className="p-3">
                    <h4 className="text-sm font-medium text-gray-900 truncate" title={file.name}>
                      {file.name}
                    </h4>
                    <div className="flex items-center justify-between mt-1">
                      <span className="text-xs text-gray-500">
                        {formatFileSize(file.size)}
                      </span>
                      {file.duration && (
                        <span className="text-xs text-gray-500">
                          {formatDuration(file.duration)}
                        </span>
                      )}
                    </div>

                    {/* Audio Controls */}
                    {file.type === 'audio' && (
                      <button
                        onClick={(e) => {
                          e.stopPropagation();
                          handleAudioPlay(file.id, file.url);
                        }}
                        className="mt-2 w-full flex items-center justify-center gap-2 px-2 py-1 bg-gray-100 hover:bg-gray-200 rounded text-xs transition-colors"
                      >
                        {playingAudio === file.id ? (
                          <>
                            <Pause className="w-3 h-3" />
                            Pause
                          </>
                        ) : (
                          <>
                            <Play className="w-3 h-3" />
                            Play
                          </>
                        )}
                      </button>
                    )}
                  </div>

                  {/* Action Buttons */}
                  <div className="absolute top-2 left-2 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1">
                    {showPreview && (
                      <button
                        onClick={(e) => {
                          e.stopPropagation();
                          setPreviewFile(file);
                        }}
                        className="p-1 bg-black bg-opacity-50 text-white rounded hover:bg-opacity-70"
                        title="Preview"
                      >
                        <Eye className="w-3 h-3" />
                      </button>
                    )}
                    <button
                      onClick={(e) => {
                        e.stopPropagation();
                        window.open(file.url, '_blank');
                      }}
                      className="p-1 bg-black bg-opacity-50 text-white rounded hover:bg-opacity-70"
                      title="Download"
                    >
                      <Download className="w-3 h-3" />
                    </button>
                    <button
                      onClick={(e) => {
                        e.stopPropagation();
                        if (confirm('Are you sure you want to delete this file?')) {
                          onFileDelete(file.id);
                        }
                      }}
                      className="p-1 bg-red-500 bg-opacity-50 text-white rounded hover:bg-opacity-70"
                      title="Delete"
                    >
                      <Trash2 className="w-3 h-3" />
                    </button>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* Hidden File Input */}
      <input
        ref={fileInputRef}
        type="file"
        multiple={multiple}
        accept={allowedTypes.join(',')}
        onChange={handleInputChange}
        className="hidden"
      />

      {/* Audio Element for Playback */}
      <audio
        ref={audioRef}
        onEnded={() => setPlayingAudio(null)}
        className="hidden"
      />

      {/* Preview Modal */}
      {previewFile && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
          <div className="bg-white rounded-lg max-w-4xl max-h-full overflow-auto">
            <div className="flex items-center justify-between p-4 border-b">
              <h3 className="text-lg font-medium">{previewFile.name}</h3>
              <button
                onClick={() => setPreviewFile(null)}
                className="p-2 hover:bg-gray-100 rounded-lg"
              >
                <X className="w-5 h-5" />
              </button>
            </div>
            <div className="p-4">
              {previewFile.type === 'image' && (
                <img
                  src={previewFile.url}
                  alt={previewFile.name}
                  className="max-w-full max-h-96 mx-auto"
                />
              )}
              {previewFile.type === 'video' && (
                <video
                  src={previewFile.url}
                  controls
                  className="max-w-full max-h-96 mx-auto"
                />
              )}
              {previewFile.type === 'audio' && (
                <div className="text-center py-8">
                  <Music className="w-16 h-16 text-gray-400 mx-auto mb-4" />
                  <audio src={previewFile.url} controls className="mx-auto" />
                </div>
              )}
              {previewFile.type === 'document' && (
                <div className="text-center py-8">
                  <File className="w-16 h-16 text-gray-400 mx-auto mb-4" />
                  <p className="text-gray-600 mb-4">Document preview not available</p>
                  <a
                    href={previewFile.url}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
                  >
                    <Download className="w-4 h-4" />
                    Download File
                  </a>
                </div>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
};