import React, { useState, useEffect, useCallback, useRef } from 'react';
import ReactDOM from 'react-dom';
import { useAuth } from '../context/AuthContext';
import { useTheme } from '../context/ThemeContext';
import { toast } from 'sonner';
import { 
  Cloud, Search, FolderPlus, Grid3X3, List, 
  MoreVertical, Download, Trash2, Edit3, Move, Copy, 
  Share2, ChevronRight, Home, Moon, Sun, LogOut, Users,
  Activity, X, Upload, Folder, File, Image,
  Film, Music, Archive, Code, FileText, HardDrive,
  Link, Shield
} from 'lucide-react';
import { formatBytes, formatDate, cn } from '../lib/utils';
import * as api from '../lib/api';

// File icon mapping
const getFileIcon = (iconType) => {
  const icons = {
    folder: Folder,
    image: Image,
    video: Film,
    audio: Music,
    archive: Archive,
    code: Code,
    pdf: FileText,
    document: FileText,
    file: File,
  };
  return icons[iconType] || File;
};

const getIconColor = (iconType) => {
  const colors = {
    folder: 'text-amber-500',
    image: 'text-purple-500',
    video: 'text-pink-500',
    audio: 'text-indigo-500',
    archive: 'text-yellow-600',
    code: 'text-emerald-500',
    pdf: 'text-red-500',
    document: 'text-blue-500',
    file: 'text-muted-foreground',
  };
  return colors[iconType] || 'text-muted-foreground';
};

// Skeleton Component
function Skeleton({ className }) {
  return <div className={cn("skeleton rounded", className)} />;
}

// Dropdown Menu Component
function DropdownMenu({ trigger, children, open, onOpenChange }) {
  const triggerRef = useRef(null);
  const menuRef = useRef(null);
  const [menuStyle, setMenuStyle] = useState({});

  useEffect(() => {
    if (open && triggerRef.current) {
      const rect = triggerRef.current.getBoundingClientRect();
      const menuWidth = 192; // w-48 = 12rem = 192px
      const menuHeight = 300; // estimated max height
      const spaceBelow = window.innerHeight - rect.bottom;
      const flipAbove = spaceBelow < menuHeight && rect.top > spaceBelow;

      setMenuStyle({
        position: 'fixed',
        right: window.innerWidth - rect.right,
        top: flipAbove ? undefined : rect.bottom + 4,
        bottom: flipAbove ? window.innerHeight - rect.top + 4 : undefined,
        width: menuWidth,
        zIndex: 9999,
      });
    }
  }, [open]);

  useEffect(() => {
    const handleClickOutside = (e) => {
      if (
        triggerRef.current && !triggerRef.current.contains(e.target) &&
        menuRef.current && !menuRef.current.contains(e.target)
      ) {
        onOpenChange(false);
      }
    };
    if (open) {
      document.addEventListener('mousedown', handleClickOutside);
    }
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [open, onOpenChange]);

  return (
    <div ref={triggerRef}>
      {trigger}
      {open && ReactDOM.createPortal(
        <div
          ref={menuRef}
          className="bg-popover border border-border rounded-lg shadow-lg py-1 animate-fade-in"
          style={menuStyle}
        >
          {children}
        </div>,
        document.body
      )}
    </div>
  );
}

function DropdownItem({ children, onClick, variant = 'default', disabled = false }) {
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      className={cn(
        "w-full px-3 py-2 text-sm text-left flex items-center gap-2 transition-colors",
        variant === 'destructive' 
          ? "text-destructive hover:bg-destructive/10" 
          : "text-popover-foreground hover:bg-accent",
        disabled && "opacity-50 cursor-not-allowed"
      )}
    >
      {children}
    </button>
  );
}

// Modal Component
function Modal({ open, onClose, title, children, size = 'md' }) {
  if (!open) return null;

  const sizeClasses = {
    sm: 'max-w-sm',
    md: 'max-w-md',
    lg: 'max-w-lg',
    xl: 'max-w-xl',
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      <div className="absolute inset-0 bg-black/50" onClick={onClose}></div>
      <div className={cn(
        "relative bg-background border border-border rounded-lg shadow-xl w-full animate-slide-up",
        sizeClasses[size]
      )}>
        <div className="flex items-center justify-between p-4 border-b border-border">
          <h3 className="font-secondary text-lg font-semibold">{title}</h3>
          <button 
            onClick={onClose}
            className="p-1 hover:bg-accent rounded-md transition-colors"
            data-testid="modal-close-btn"
          >
            <X className="w-5 h-5" />
          </button>
        </div>
        <div className="p-4">{children}</div>
      </div>
    </div>
  );
}

// Storage Usage Component
function StorageUsage({ used, quota }) {
  const percentage = quota > 0 ? (used / quota) * 100 : 0;
  const isWarning = percentage > 80;
  const isCritical = percentage > 95;

  return (
    <div className="p-4 bg-card border border-border rounded-lg">
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-2">
          <HardDrive className="w-4 h-4 text-muted-foreground" />
          <span className="text-sm font-medium">Storage</span>
        </div>
        <span className="text-sm text-muted-foreground">
          {formatBytes(used)} / {formatBytes(quota)}
        </span>
      </div>
      <div className="h-2 bg-muted rounded-full overflow-hidden">
        <div 
          className={cn(
            "h-full transition-all duration-300",
            isCritical ? "bg-destructive" : isWarning ? "bg-amber-500" : "bg-primary"
          )}
          style={{ width: `${Math.min(percentage, 100)}%` }}
        />
      </div>
      <p className="text-xs text-muted-foreground mt-2">
        {percentage.toFixed(1)}% used
      </p>
    </div>
  );
}

// Main Dashboard Component
function Dashboard() {
  const { user, logout, updateUser } = useAuth();
  const { theme, toggleTheme } = useTheme();
  
  // State
  const [files, setFiles] = useState([]);
  const [loading, setLoading] = useState(true);
  const [currentFolder, setCurrentFolder] = useState(null);
  const [breadcrumb, setBreadcrumb] = useState([]);
  const [viewMode, setViewMode] = useState('list');
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedFiles, setSelectedFiles] = useState(new Set());
  const [menuOpenId, setMenuOpenId] = useState(null);
  const [stats, setStats] = useState(null);
  
  // Modal states
  const [showNewFolder, setShowNewFolder] = useState(false);
  const [showRename, setShowRename] = useState(null);
  const [showShare, setShowShare] = useState(null);
  const [showUsers, setShowUsers] = useState(false);
  const [showActivity, setShowActivity] = useState(false);
  const [showMoveModal, setShowMoveModal] = useState(null);
  
  // Form states
  const [newFolderName, setNewFolderName] = useState('');
  const [renameValue, setRenameValue] = useState('');
  const [shareExpiry, setShareExpiry] = useState(24);
  const [sharePassword, setSharePassword] = useState('');
  
  // Upload state
  const [uploadProgress, setUploadProgress] = useState({});
  const [isDragging, setIsDragging] = useState(false);
  const fileInputRef = useRef(null);
  
  // Users state
  const [users, setUsers] = useState([]);
  const [loadingUsers, setLoadingUsers] = useState(false);
  const [showUserForm, setShowUserForm] = useState(false);
  const [editingUser, setEditingUser] = useState(null);
  const [userForm, setUserForm] = useState({ username: '', password: '', name: '', role: 'user', storage_quota: 10737418240 });
  
  // Activity state
  const [activities, setActivities] = useState([]);
  const [loadingActivity, setLoadingActivity] = useState(false);

  // Folders for move modal
  const [availableFolders, setAvailableFolders] = useState([]);

  // Load files
  const loadFiles = useCallback(async () => {
    setLoading(true);
    try {
      const response = await api.getFiles(currentFolder, searchQuery || null);
      setFiles(response.data);
      setSelectedFiles(new Set());
    } catch (error) {
      toast.error('Failed to load files');
    } finally {
      setLoading(false);
    }
  }, [currentFolder, searchQuery]);

  // Load breadcrumb
  const loadBreadcrumb = useCallback(async () => {
    if (!currentFolder) {
      setBreadcrumb([]);
      return;
    }
    try {
      const response = await api.getBreadcrumb(currentFolder);
      setBreadcrumb(response.data);
    } catch (error) {
      console.error('Failed to load breadcrumb');
    }
  }, [currentFolder]);

  // Load stats
  const loadStats = useCallback(async () => {
    try {
      const response = await api.getStats();
      setStats(response.data);
      updateUser({ storage_used: response.data.storage_used });
    } catch (error) {
      console.error('Failed to load stats');
    }
  }, [updateUser]);

  useEffect(() => {
    loadFiles();
    loadBreadcrumb();
    loadStats();
  }, [loadFiles, loadBreadcrumb, loadStats]);

  // Navigate to folder
  const navigateToFolder = (folderId) => {
    setCurrentFolder(folderId);
    setSearchQuery('');
  };

  // Handle file click
  const handleFileClick = (file) => {
    if (file.is_folder) {
      navigateToFolder(file.id);
    } else {
      window.open(api.getDownloadUrl(file.id), '_blank');
    }
  };

  // Create folder
  const handleCreateFolder = async () => {
    if (!newFolderName.trim()) {
      toast.error('Please enter a folder name');
      return;
    }
    try {
      await api.createFolder(newFolderName, currentFolder);
      toast.success('Folder created');
      setShowNewFolder(false);
      setNewFolderName('');
      loadFiles();
      loadStats();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to create folder');
    }
  };

  // Rename file
  const handleRename = async () => {
    if (!renameValue.trim() || !showRename) return;
    try {
      await api.renameFile(showRename.id, renameValue);
      toast.success('Renamed successfully');
      setShowRename(null);
      setRenameValue('');
      loadFiles();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to rename');
    }
  };

  // Delete file
  const handleDelete = async (file) => {
    if (!window.confirm(`Delete "${file.name}"? This cannot be undone.`)) return;
    try {
      await api.deleteFile(file.id);
      toast.success('Deleted successfully');
      loadFiles();
      loadStats();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to delete');
    }
  };

  // Bulk delete
  const handleBulkDelete = async () => {
    if (selectedFiles.size === 0) return;
    if (!window.confirm(`Delete ${selectedFiles.size} items? This cannot be undone.`)) return;
    try {
      await api.bulkDeleteFiles(Array.from(selectedFiles));
      toast.success(`Deleted ${selectedFiles.size} items`);
      setSelectedFiles(new Set());
      loadFiles();
      loadStats();
    } catch (error) {
      toast.error('Failed to delete items');
    }
  };

  // Upload files
  const handleUpload = async (fileList) => {
    const filesToUpload = Array.from(fileList);
    
    for (const file of filesToUpload) {
      const uploadId = `${file.name}-${Date.now()}`;
      setUploadProgress(prev => ({ ...prev, [uploadId]: 0 }));
      
      try {
        await api.uploadFile(file, currentFolder, (progress) => {
          setUploadProgress(prev => ({ ...prev, [uploadId]: progress }));
        });
        toast.success(`Uploaded "${file.name}"`);
      } catch (error) {
        toast.error(`Failed to upload "${file.name}"`);
      } finally {
        setUploadProgress(prev => {
          const { [uploadId]: _, ...rest } = prev;
          return rest;
        });
      }
    }
    
    loadFiles();
    loadStats();
  };

  // Drag and drop handlers
  const handleDragOver = (e) => {
    e.preventDefault();
    setIsDragging(true);
  };

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

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

  // Create share link
  const handleCreateShare = async () => {
    if (!showShare) return;
    try {
      const response = await api.createShare(
        showShare.id,
        shareExpiry,
        sharePassword || null
      );
      const shareUrl = `${window.location.origin}/share/${response.data.token}`;
      try {
        await navigator.clipboard.writeText(shareUrl);
        toast.success('Share link copied to clipboard!');
      } catch {
        // Clipboard API fails on non-HTTPS — fallback
        window.prompt('Copy this share link:', shareUrl);
        toast.success('Share link created!');
      }
      setShowShare(null);
      setShareExpiry(24);
      setSharePassword('');
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to create share link');
    }
  };

  // Load users (admin)
  const loadUsers = async () => {
    setLoadingUsers(true);
    try {
      const response = await api.getUsers();
      setUsers(response.data);
    } catch (error) {
      toast.error('Failed to load users');
    } finally {
      setLoadingUsers(false);
    }
  };

  // Load activity
  const loadActivity = async () => {
    setLoadingActivity(true);
    try {
      const response = await api.getActivity(50);
      setActivities(response.data);
    } catch (error) {
      toast.error('Failed to load activity');
    } finally {
      setLoadingActivity(false);
    }
  };

  // Handle user form submit
  const handleUserSubmit = async () => {
    if (!userForm.username || !userForm.name || (!editingUser && !userForm.password)) {
      toast.error('Please fill all required fields');
      return;
    }
    try {
      if (editingUser) {
        const updateData = { name: userForm.name, role: userForm.role, storage_quota: userForm.storage_quota };
        if (userForm.password) updateData.password = userForm.password;
        await api.updateUser(editingUser.id, updateData);
        toast.success('User updated');
      } else {
        await api.createUser(userForm);
        toast.success('User created');
      }
      setShowUserForm(false);
      setEditingUser(null);
      setUserForm({ username: '', password: '', name: '', role: 'user', storage_quota: 10737418240 });
      loadUsers();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to save user');
    }
  };

  // Delete user
  const handleDeleteUser = async (userId) => {
    if (!window.confirm('Delete this user? This cannot be undone.')) return;
    try {
      await api.deleteUser(userId);
      toast.success('User deleted');
      loadUsers();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to delete user');
    }
  };

  // Toggle file selection
  const toggleFileSelection = (fileId) => {
    setSelectedFiles(prev => {
      const newSet = new Set(prev);
      if (newSet.has(fileId)) {
        newSet.delete(fileId);
      } else {
        newSet.add(fileId);
      }
      return newSet;
    });
  };

  // Select all
  const selectAll = () => {
    if (selectedFiles.size === files.length) {
      setSelectedFiles(new Set());
    } else {
      setSelectedFiles(new Set(files.map(f => f.id)));
    }
  };

  // Load folders for move modal
  const loadFolders = async () => {
    try {
      const response = await api.getFiles(null);
      const folders = response.data.filter(f => f.is_folder);
      setAvailableFolders(folders);
    } catch (error) {
      console.error('Failed to load folders');
    }
  };

  // Handle move
  const handleMove = async (destinationId) => {
    if (!showMoveModal) return;
    try {
      await api.moveFile(showMoveModal.id, destinationId);
      toast.success('Moved successfully');
      setShowMoveModal(null);
      loadFiles();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to move');
    }
  };

  // Handle copy
  const handleCopy = async (file) => {
    try {
      await api.copyFile(file.id, currentFolder);
      toast.success('Copied successfully');
      loadFiles();
      loadStats();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to copy');
    }
  };

  // Download as ZIP
  const downloadZip = async (fileIds) => {
    try {
      toast.info('Preparing ZIP...');
      const token = localStorage.getItem('token');
      const response = await fetch('/api/download-zip', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`
        },
        body: JSON.stringify({ items: fileIds })
      });
      if (!response.ok) {
        const err = await response.json();
        throw new Error(err.detail || 'ZIP failed');
      }
      const disposition = response.headers.get('Content-Disposition') || '';
      const match = disposition.match(/filename="(.+)"/);
      const filename = match ? match[1] : 'download.zip';
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      toast.success('ZIP downloaded');
    } catch (err) {
      toast.error(err.message || 'Failed to download ZIP');
    }
  };

  const isAdmin = user?.role === 'admin';

  return (
    <div 
      className="min-h-screen bg-background"
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
    >
      {/* Header */}
      <header className="sticky top-0 z-40 bg-card border-b border-border">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <div className="flex items-center justify-between h-16">
            <div className="flex items-center gap-3">
              <div className="w-9 h-9 bg-primary rounded-lg flex items-center justify-center">
                <Cloud className="w-5 h-5 text-primary-foreground" />
              </div>
              <span className="font-secondary text-xl font-bold hidden sm:inline">CloudSync</span>
            </div>

            <div className="flex items-center gap-2">
              {isAdmin && (
                <>
                  <button
                    onClick={() => { setShowUsers(true); loadUsers(); }}
                    data-testid="users-btn"
                    className="p-2 hover:bg-accent rounded-lg transition-colors text-muted-foreground hover:text-foreground"
                    title="User Management"
                  >
                    <Users className="w-5 h-5" />
                  </button>
                  <button
                    onClick={() => { setShowActivity(true); loadActivity(); }}
                    data-testid="activity-btn"
                    className="p-2 hover:bg-accent rounded-lg transition-colors text-muted-foreground hover:text-foreground"
                    title="Activity Log"
                  >
                    <Activity className="w-5 h-5" />
                  </button>
                </>
              )}
              
              <button
                onClick={toggleTheme}
                data-testid="theme-toggle-btn"
                className="p-2 hover:bg-accent rounded-lg transition-colors text-muted-foreground hover:text-foreground"
                title={theme === 'dark' ? 'Light mode' : 'Dark mode'}
              >
                {theme === 'dark' ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
              </button>

              <div className="hidden sm:flex items-center gap-2 px-3 py-1.5 bg-muted rounded-lg">
                <span className="text-sm font-medium">{user?.name}</span>
                {isAdmin && <Shield className="w-4 h-4 text-primary" />}
              </div>

              <button
                onClick={logout}
                data-testid="logout-btn"
                className="p-2 hover:bg-destructive/10 text-muted-foreground hover:text-destructive rounded-lg transition-colors"
                title="Logout"
              >
                <LogOut className="w-5 h-5" />
              </button>
            </div>
          </div>
        </div>
      </header>

      {/* Main Content */}
      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6">
        {/* Storage & Stats */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <StorageUsage 
            used={stats?.storage_used || user?.storage_used || 0} 
            quota={stats?.storage_quota || user?.storage_quota || 10737418240} 
          />
          
          <div className="p-4 bg-card border border-border rounded-lg">
            <div className="flex items-center gap-2 mb-2">
              <File className="w-4 h-4 text-muted-foreground" />
              <span className="text-sm font-medium">Files</span>
            </div>
            <p className="text-2xl font-bold font-secondary">{stats?.total_files || 0}</p>
            <p className="text-xs text-muted-foreground mt-1">{stats?.total_folders || 0} folders</p>
          </div>

          <div className="p-4 bg-card border border-border rounded-lg">
            <div className="flex items-center gap-2 mb-2">
              <Share2 className="w-4 h-4 text-muted-foreground" />
              <span className="text-sm font-medium">Active Shares</span>
            </div>
            <p className="text-2xl font-bold font-secondary">{stats?.active_shares || 0}</p>
            <p className="text-xs text-muted-foreground mt-1">Shared links</p>
          </div>
        </div>

        {/* File Browser */}
        <div className="bg-card border border-border rounded-lg">
          {/* Toolbar */}
          <div className="p-4 border-b border-border">
            <div className="flex flex-col sm:flex-row gap-4">
              {/* Search */}
              <div className="relative flex-1">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
                <input
                  type="text"
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  placeholder="Search files..."
                  data-testid="search-input"
                  className="w-full h-10 pl-10 pr-4 bg-background border border-input rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-ring"
                />
              </div>

              {/* Actions */}
              <div className="flex items-center gap-2">
                <button
                  onClick={() => setShowNewFolder(true)}
                  data-testid="new-folder-btn"
                  className="h-10 px-4 bg-secondary text-secondary-foreground text-sm font-medium rounded-lg hover:opacity-80 transition-colors flex items-center gap-2"
                >
                  <FolderPlus className="w-4 h-4" />
                  <span className="hidden sm:inline">New Folder</span>
                </button>
                
                <button
                  onClick={() => fileInputRef.current?.click()}
                  data-testid="upload-btn"
                  className="h-10 px-4 bg-primary text-primary-foreground text-sm font-medium rounded-lg hover:opacity-90 transition-colors flex items-center gap-2"
                >
                  <Upload className="w-4 h-4" />
                  <span className="hidden sm:inline">Upload</span>
                </button>
                <input
                  ref={fileInputRef}
                  type="file"
                  multiple
                  onChange={(e) => handleUpload(e.target.files)}
                  className="hidden"
                  data-testid="file-input"
                />

                {/* View toggle */}
                <div className="flex items-center border border-border rounded-lg overflow-hidden">
                  <button
                    onClick={() => setViewMode('list')}
                    data-testid="view-list-btn"
                    className={cn(
                      "p-2 transition-colors",
                      viewMode === 'list' ? "bg-accent" : "hover:bg-accent/50"
                    )}
                  >
                    <List className="w-4 h-4" />
                  </button>
                  <button
                    onClick={() => setViewMode('grid')}
                    data-testid="view-grid-btn"
                    className={cn(
                      "p-2 transition-colors",
                      viewMode === 'grid' ? "bg-accent" : "hover:bg-accent/50"
                    )}
                  >
                    <Grid3X3 className="w-4 h-4" />
                  </button>
                </div>
              </div>
            </div>

            {/* Breadcrumb */}
            <nav className="flex items-center gap-1 mt-4 text-sm flex-wrap">
              <button
                onClick={() => navigateToFolder(null)}
                data-testid="breadcrumb-home"
                className="flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors"
              >
                <Home className="w-4 h-4" />
                <span>Home</span>
              </button>
              {breadcrumb.map((item, index) => (
                <React.Fragment key={item.id}>
                  <ChevronRight className="w-4 h-4 text-muted-foreground" />
                  <button
                    onClick={() => navigateToFolder(item.id)}
                    data-testid={`breadcrumb-${item.id}`}
                    className={cn(
                      "transition-colors",
                      index === breadcrumb.length - 1 
                        ? "font-medium text-foreground" 
                        : "text-muted-foreground hover:text-foreground"
                    )}
                  >
                    {item.name}
                  </button>
                </React.Fragment>
              ))}
            </nav>

            {/* Bulk Actions */}
            {selectedFiles.size > 0 && (
              <div className="flex items-center gap-3 mt-4 p-3 bg-muted rounded-lg animate-fade-in">
                <span className="text-sm font-medium">{selectedFiles.size} selected</span>
                <button
                  onClick={() => downloadZip(Array.from(selectedFiles))}
                  data-testid="bulk-zip-btn"
                  className="px-3 py-1.5 text-sm bg-primary text-primary-foreground rounded-lg hover:opacity-90 flex items-center gap-1"
                >
                  <Archive className="w-4 h-4" />
                  Download ZIP
                </button>
                <button
                  onClick={handleBulkDelete}
                  data-testid="bulk-delete-btn"
                  className="px-3 py-1.5 text-sm bg-destructive text-destructive-foreground rounded-lg hover:opacity-90 flex items-center gap-1"
                >
                  <Trash2 className="w-4 h-4" />
                  Delete
                </button>
                <button
                  onClick={() => setSelectedFiles(new Set())}
                  className="px-3 py-1.5 text-sm bg-secondary text-secondary-foreground rounded-lg hover:opacity-80"
                >
                  Clear
                </button>
              </div>
            )}
          </div>

          {/* Upload progress */}
          {Object.keys(uploadProgress).length > 0 && (
            <div className="p-4 border-b border-border bg-muted/50">
              {Object.entries(uploadProgress).map(([id, progress]) => (
                <div key={id} className="flex items-center gap-3 mb-2 last:mb-0">
                  <Upload className="w-4 h-4 text-muted-foreground animate-pulse" />
                  <div className="flex-1">
                    <div className="h-2 bg-muted rounded-full overflow-hidden">
                      <div 
                        className="h-full bg-primary transition-all duration-300"
                        style={{ width: `${progress}%` }}
                      />
                    </div>
                  </div>
                  <span className="text-sm text-muted-foreground">{progress}%</span>
                </div>
              ))}
            </div>
          )}

          {/* File List */}
          <div className="p-4">
            {loading ? (
              // Skeleton loader
              <div className="space-y-2">
                {[...Array(5)].map((_, i) => (
                  <div key={i} className="flex items-center gap-4 p-3">
                    <Skeleton className="w-5 h-5" />
                    <Skeleton className="w-8 h-8 rounded" />
                    <Skeleton className="flex-1 h-4" />
                    <Skeleton className="w-20 h-4" />
                    <Skeleton className="w-24 h-4" />
                  </div>
                ))}
              </div>
            ) : files.length === 0 ? (
              // Empty state
              <div className="py-12 text-center">
                <Folder className="w-12 h-12 text-muted-foreground mx-auto mb-4" />
                <h3 className="font-secondary text-lg font-medium mb-1">No files yet</h3>
                <p className="text-muted-foreground text-sm">
                  {searchQuery ? 'No files match your search' : 'Upload files or create a folder to get started'}
                </p>
              </div>
            ) : viewMode === 'list' ? (
              // List view
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="text-left text-muted-foreground border-b border-border">
                      <th className="pb-3 pl-2 w-8">
                        <input 
                          type="checkbox"
                          checked={selectedFiles.size === files.length && files.length > 0}
                          onChange={selectAll}
                          data-testid="select-all-checkbox"
                          className="rounded border-input"
                        />
                      </th>
                      <th className="pb-3 w-10">Type</th>
                      <th className="pb-3">Name</th>
                      <th className="pb-3 hidden sm:table-cell">Size</th>
                      <th className="pb-3 hidden md:table-cell">Modified</th>
                      <th className="pb-3 w-12"></th>
                    </tr>
                  </thead>
                  <tbody>
                    {files.map((file, index) => {
                      const FileIcon = getFileIcon(file.icon);
                      const iconColor = getIconColor(file.icon);
                      
                      return (
                        <tr 
                          key={file.id}
                          className="border-b border-border/50 hover:bg-accent/50 transition-colors animate-slide-up"
                          style={{ animationDelay: `${index * 30}ms` }}
                        >
                          <td className="py-3 pl-2">
                            <input
                              type="checkbox"
                              checked={selectedFiles.has(file.id)}
                              onChange={() => toggleFileSelection(file.id)}
                              data-testid={`file-checkbox-${file.id}`}
                              className="rounded border-input"
                            />
                          </td>
                          <td className="py-3">
                            <FileIcon className={cn("w-5 h-5", iconColor)} />
                          </td>
                          <td className="py-3">
                            <button
                              onClick={() => handleFileClick(file)}
                              data-testid={`file-name-${file.id}`}
                              className="font-medium hover:text-primary transition-colors text-left truncate max-w-xs block"
                            >
                              {file.name}
                            </button>
                          </td>
                          <td className="py-3 text-muted-foreground hidden sm:table-cell">
                            {formatBytes(file.size)}
                          </td>
                          <td className="py-3 text-muted-foreground hidden md:table-cell">
                            {formatDate(file.modified_at)}
                          </td>
                          <td className="py-3">
                            <DropdownMenu
                              open={menuOpenId === file.id}
                              onOpenChange={(open) => setMenuOpenId(open ? file.id : null)}
                              trigger={
                                <button
                                  onClick={() => setMenuOpenId(menuOpenId === file.id ? null : file.id)}
                                  data-testid={`file-menu-${file.id}`}
                                  className="p-1.5 hover:bg-accent rounded-md transition-colors"
                                >
                                  <MoreVertical className="w-4 h-4" />
                                </button>
                              }
                            >
                              {file.is_folder && (
                                <DropdownItem onClick={() => downloadZip([file.id])}>
                                  <Archive className="w-4 h-4" /> Download ZIP
                                </DropdownItem>
                              )}
                              {!file.is_folder && (
                                <>
                                  <DropdownItem onClick={() => window.open(api.getDownloadUrl(file.id), '_blank')}>
                                    <Download className="w-4 h-4" /> Download
                                  </DropdownItem>
                                  <DropdownItem onClick={() => downloadZip([file.id])}>
                                    <Archive className="w-4 h-4" /> Download ZIP
                                  </DropdownItem>
                                  <DropdownItem onClick={() => setShowShare(file)}>
                                    <Share2 className="w-4 h-4" /> Share
                                  </DropdownItem>
                                  <DropdownItem onClick={() => handleCopy(file)}>
                                    <Copy className="w-4 h-4" /> Copy
                                  </DropdownItem>
                                </>
                              )}
                              <DropdownItem onClick={() => { setShowRename(file); setRenameValue(file.name); }}>
                                <Edit3 className="w-4 h-4" /> Rename
                              </DropdownItem>
                              <DropdownItem onClick={() => { setShowMoveModal(file); loadFolders(); }}>
                                <Move className="w-4 h-4" /> Move
                              </DropdownItem>
                              <DropdownItem onClick={() => handleDelete(file)} variant="destructive">
                                <Trash2 className="w-4 h-4" /> Delete
                              </DropdownItem>
                            </DropdownMenu>
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            ) : (
              // Grid view
              <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
                {files.map((file, index) => {
                  const FileIcon = getFileIcon(file.icon);
                  const iconColor = getIconColor(file.icon);
                  
                  return (
                    <div
                      key={file.id}
                      className="group p-4 bg-background border border-border rounded-lg hover:border-primary/50 hover:shadow-md transition-all cursor-pointer animate-slide-up"
                      style={{ animationDelay: `${index * 30}ms` }}
                      onClick={() => handleFileClick(file)}
                      data-testid={`file-grid-${file.id}`}
                    >
                      <div className="flex items-center justify-between mb-3">
                        <FileIcon className={cn("w-8 h-8", iconColor)} />
                        <button
                          onClick={(e) => { e.stopPropagation(); setMenuOpenId(menuOpenId === file.id ? null : file.id); }}
                          className="p-1 opacity-0 group-hover:opacity-100 hover:bg-accent rounded transition-all"
                        >
                          <MoreVertical className="w-4 h-4" />
                        </button>
                      </div>
                      <p className="font-medium truncate text-sm">{file.name}</p>
                      <p className="text-xs text-muted-foreground mt-1">
                        {formatBytes(file.size)}
                      </p>
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        </div>

        {/* Drag overlay */}
        {isDragging && (
          <div className="fixed inset-0 z-50 bg-background/80 backdrop-blur-sm flex items-center justify-center animate-fade-in">
            <div className="p-8 border-2 border-dashed border-primary rounded-xl bg-card">
              <Upload className="w-12 h-12 text-primary mx-auto mb-4" />
              <p className="text-lg font-medium text-center">Drop files to upload</p>
            </div>
          </div>
        )}
      </main>

      {/* New Folder Modal */}
      <Modal open={showNewFolder} onClose={() => setShowNewFolder(false)} title="New Folder">
        <div className="space-y-4">
          <input
            type="text"
            value={newFolderName}
            onChange={(e) => setNewFolderName(e.target.value)}
            placeholder="Folder name"
            data-testid="new-folder-input"
            className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
            autoFocus
            onKeyDown={(e) => e.key === 'Enter' && handleCreateFolder()}
          />
          <div className="flex gap-3">
            <button
              onClick={() => setShowNewFolder(false)}
              className="flex-1 h-10 bg-secondary text-secondary-foreground rounded-lg hover:opacity-80"
            >
              Cancel
            </button>
            <button
              onClick={handleCreateFolder}
              data-testid="create-folder-btn"
              className="flex-1 h-10 bg-primary text-primary-foreground rounded-lg hover:opacity-90"
            >
              Create
            </button>
          </div>
        </div>
      </Modal>

      {/* Rename Modal */}
      <Modal open={!!showRename} onClose={() => setShowRename(null)} title="Rename">
        <div className="space-y-4">
          <input
            type="text"
            value={renameValue}
            onChange={(e) => setRenameValue(e.target.value)}
            placeholder="New name"
            data-testid="rename-input"
            className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
            autoFocus
            onKeyDown={(e) => e.key === 'Enter' && handleRename()}
          />
          <div className="flex gap-3">
            <button
              onClick={() => setShowRename(null)}
              className="flex-1 h-10 bg-secondary text-secondary-foreground rounded-lg hover:opacity-80"
            >
              Cancel
            </button>
            <button
              onClick={handleRename}
              data-testid="rename-confirm-btn"
              className="flex-1 h-10 bg-primary text-primary-foreground rounded-lg hover:opacity-90"
            >
              Rename
            </button>
          </div>
        </div>
      </Modal>

      {/* Share Modal */}
      <Modal open={!!showShare} onClose={() => setShowShare(null)} title="Share File" size="lg">
        <div className="space-y-4">
          <p className="text-sm text-muted-foreground">
            Create a share link for <span className="font-medium text-foreground">{showShare?.name}</span>
          </p>
          
          <div>
            <label className="block text-sm font-medium mb-2">Link expires in</label>
            <select
              value={shareExpiry}
              onChange={(e) => setShareExpiry(Number(e.target.value))}
              data-testid="share-expiry-select"
              className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
            >
              <option value={1}>1 hour</option>
              <option value={24}>1 day</option>
              <option value={168}>1 week</option>
              <option value={720}>30 days</option>
            </select>
          </div>

          <div>
            <label className="block text-sm font-medium mb-2">Password (optional)</label>
            <input
              type="password"
              value={sharePassword}
              onChange={(e) => setSharePassword(e.target.value)}
              placeholder="Leave empty for no password"
              data-testid="share-password-input"
              className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
            />
          </div>

          <div className="flex gap-3 pt-2">
            <button
              onClick={() => setShowShare(null)}
              className="flex-1 h-10 bg-secondary text-secondary-foreground rounded-lg hover:opacity-80"
            >
              Cancel
            </button>
            <button
              onClick={handleCreateShare}
              data-testid="create-share-btn"
              className="flex-1 h-10 bg-primary text-primary-foreground rounded-lg hover:opacity-90 flex items-center justify-center gap-2"
            >
              <Link className="w-4 h-4" />
              Create Link
            </button>
          </div>
        </div>
      </Modal>

      {/* Move Modal */}
      <Modal open={!!showMoveModal} onClose={() => setShowMoveModal(null)} title="Move to">
        <div className="space-y-4">
          <button
            onClick={() => handleMove(null)}
            className="w-full p-3 text-left hover:bg-accent rounded-lg transition-colors flex items-center gap-3"
            data-testid="move-to-root"
          >
            <Home className="w-5 h-5 text-muted-foreground" />
            <span>Home (Root)</span>
          </button>
          {availableFolders
            .filter(f => f.id !== showMoveModal?.id)
            .map(folder => (
              <button
                key={folder.id}
                onClick={() => handleMove(folder.id)}
                className="w-full p-3 text-left hover:bg-accent rounded-lg transition-colors flex items-center gap-3"
                data-testid={`move-to-${folder.id}`}
              >
                <Folder className="w-5 h-5 text-amber-500" />
                <span>{folder.name}</span>
              </button>
            ))
          }
        </div>
      </Modal>

      {/* Users Modal (Admin) */}
      <Modal open={showUsers} onClose={() => { setShowUsers(false); setShowUserForm(false); }} title="User Management" size="xl">
        {showUserForm ? (
          <div className="space-y-4">
            <div>
              <label className="block text-sm font-medium mb-2">Username</label>
              <input
                type="text"
                value={userForm.username}
                onChange={(e) => setUserForm(prev => ({ ...prev, username: e.target.value }))}
                disabled={!!editingUser}
                data-testid="user-username-input"
                className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
              />
            </div>
            <div>
              <label className="block text-sm font-medium mb-2">
                Password {editingUser && <span className="text-muted-foreground">(leave empty to keep current)</span>}
              </label>
              <input
                type="password"
                value={userForm.password}
                onChange={(e) => setUserForm(prev => ({ ...prev, password: e.target.value }))}
                data-testid="user-password-input"
                className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
              />
            </div>
            <div>
              <label className="block text-sm font-medium mb-2">Name</label>
              <input
                type="text"
                value={userForm.name}
                onChange={(e) => setUserForm(prev => ({ ...prev, name: e.target.value }))}
                data-testid="user-name-input"
                className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
              />
            </div>
            <div>
              <label className="block text-sm font-medium mb-2">Role</label>
              <select
                value={userForm.role}
                onChange={(e) => setUserForm(prev => ({ ...prev, role: e.target.value }))}
                data-testid="user-role-select"
                className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
              >
                <option value="user">User</option>
                <option value="admin">Admin</option>
              </select>
            </div>
            <div>
              <label className="block text-sm font-medium mb-2">Storage Quota</label>
              <select
                value={userForm.storage_quota}
                onChange={(e) => setUserForm(prev => ({ ...prev, storage_quota: Number(e.target.value) }))}
                data-testid="user-quota-select"
                className="w-full h-10 px-4 bg-background border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
              >
                <option value={1073741824}>1 GB</option>
                <option value={5368709120}>5 GB</option>
                <option value={10737418240}>10 GB</option>
                <option value={53687091200}>50 GB</option>
                <option value={107374182400}>100 GB</option>
              </select>
            </div>
            <div className="flex gap-3 pt-2">
              <button
                onClick={() => { setShowUserForm(false); setEditingUser(null); setUserForm({ username: '', password: '', name: '', role: 'user', storage_quota: 10737418240 }); }}
                className="flex-1 h-10 bg-secondary text-secondary-foreground rounded-lg hover:opacity-80"
              >
                Cancel
              </button>
              <button
                onClick={handleUserSubmit}
                data-testid="save-user-btn"
                className="flex-1 h-10 bg-primary text-primary-foreground rounded-lg hover:opacity-90"
              >
                {editingUser ? 'Update' : 'Create'}
              </button>
            </div>
          </div>
        ) : (
          <div className="space-y-4">
            <button
              onClick={() => setShowUserForm(true)}
              data-testid="add-user-btn"
              className="w-full h-10 bg-primary text-primary-foreground rounded-lg hover:opacity-90 flex items-center justify-center gap-2"
            >
              <Users className="w-4 h-4" />
              Add User
            </button>

            {loadingUsers ? (
              <div className="space-y-2">
                {[...Array(3)].map((_, i) => (
                  <div key={i} className="flex items-center gap-4 p-3">
                    <Skeleton className="w-10 h-10 rounded-full" />
                    <Skeleton className="flex-1 h-4" />
                    <Skeleton className="w-20 h-4" />
                  </div>
                ))}
              </div>
            ) : (
              <div className="divide-y divide-border">
                {users.map(u => (
                  <div key={u.id} className="py-3 flex items-center justify-between">
                    <div className="flex items-center gap-3">
                      <div className="w-10 h-10 bg-muted rounded-full flex items-center justify-center">
                        <span className="font-medium">{u.name.charAt(0).toUpperCase()}</span>
                      </div>
                      <div>
                        <p className="font-medium">{u.name}</p>
                        <p className="text-sm text-muted-foreground">@{u.username} · {u.role}</p>
                      </div>
                    </div>
                    <div className="flex items-center gap-2">
                      <span className="text-sm text-muted-foreground">
                        {formatBytes(u.storage_used)} / {formatBytes(u.storage_quota)}
                      </span>
                      <button
                        onClick={() => { setEditingUser(u); setUserForm({ username: u.username, password: '', name: u.name, role: u.role, storage_quota: u.storage_quota }); setShowUserForm(true); }}
                        className="p-2 hover:bg-accent rounded-lg"
                        data-testid={`edit-user-${u.id}`}
                      >
                        <Edit3 className="w-4 h-4" />
                      </button>
                      {u.id !== user.id && (
                        <button
                          onClick={() => handleDeleteUser(u.id)}
                          className="p-2 hover:bg-destructive/10 text-destructive rounded-lg"
                          data-testid={`delete-user-${u.id}`}
                        >
                          <Trash2 className="w-4 h-4" />
                        </button>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </Modal>

      {/* Activity Modal (Admin) */}
      <Modal open={showActivity} onClose={() => setShowActivity(false)} title="Activity Log" size="xl">
        <div className="max-h-96 overflow-y-auto">
          {loadingActivity ? (
            <div className="space-y-2">
              {[...Array(5)].map((_, i) => (
                <div key={i} className="flex items-center gap-4 p-3">
                  <Skeleton className="w-8 h-8 rounded" />
                  <Skeleton className="flex-1 h-4" />
                  <Skeleton className="w-24 h-4" />
                </div>
              ))}
            </div>
          ) : activities.length === 0 ? (
            <div className="py-8 text-center text-muted-foreground">
              <Activity className="w-8 h-8 mx-auto mb-2" />
              <p>No activity yet</p>
            </div>
          ) : (
            <div className="divide-y divide-border">
              {activities.map(activity => (
                <div key={activity.id} className="py-3 flex items-center gap-4">
                  <div className={cn(
                    "w-8 h-8 rounded-lg flex items-center justify-center",
                    activity.action === 'delete' ? 'bg-destructive/10 text-destructive' : 'bg-muted'
                  )}>
                    {activity.action === 'upload' && <Upload className="w-4 h-4" />}
                    {activity.action === 'download' && <Download className="w-4 h-4" />}
                    {activity.action === 'delete' && <Trash2 className="w-4 h-4" />}
                    {activity.action === 'create' && <FolderPlus className="w-4 h-4" />}
                    {activity.action === 'rename' && <Edit3 className="w-4 h-4" />}
                    {activity.action === 'move' && <Move className="w-4 h-4" />}
                    {activity.action === 'share' && <Share2 className="w-4 h-4" />}
                    {activity.action === 'login' && <LogOut className="w-4 h-4" />}
                    {!['upload', 'download', 'delete', 'create', 'rename', 'move', 'share', 'login'].includes(activity.action) && <Activity className="w-4 h-4" />}
                  </div>
                  <div className="flex-1 min-w-0">
                    <p className="text-sm">
                      <span className="font-medium">{activity.user_name}</span>
                      {' '}{activity.action}{' '}
                      <span className="text-muted-foreground">{activity.resource_type}</span>
                      {' '}<span className="font-medium truncate">{activity.resource_name}</span>
                    </p>
                  </div>
                  <span className="text-xs text-muted-foreground whitespace-nowrap">
                    {formatDate(activity.created_at)}
                  </span>
                </div>
              ))}
            </div>
          )}
        </div>
      </Modal>
    </div>
  );
}

export default Dashboard;
