import React, { useState, useMemo, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  File,
  Folder,
  FolderOpen,
  Grid3x3,
  List,
  Search,
  Edit2,
  Trash2,
  MoreVertical,
  Lock,
  LockOpen,
} from 'lucide-react';
import { useEditorStore } from '@/core/store';
import { useSecurity } from '@/contexts/SecurityContext';
import { useSecureFileOpen } from '@/hooks/useSecureFileOpen';
import { isSecureItem, getSecureFolderId } from '@/lib/security-utils';
import { SecureUnlockDialog } from '@/components/SecureUnlockDialog';
import { FileIcon } from '@/lib/file-icons';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { appleSpringGentle, appleListItem } from '@/lib/apple-animations';
import { toast } from 'sonner';
import type { FileNode } from '@/core/types';

type ViewMode = 'grid' | 'list';

export const FileManager: React.FC = () => {
  const { files, deleteFile, updateFile, openFile } = useEditorStore();
  const { isUnlocked, lockItem } = useSecurity();
  const { openFile: secureOpenFile, UnlockDialog } = useSecureFileOpen();
  const [viewMode, setViewMode] = useState<ViewMode>('grid');
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedItem, setSelectedItem] = useState<string | null>(null);
  const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
  const [itemToDelete, setItemToDelete] = useState<string | null>(null);
  const [showUnlockDialog, setShowUnlockDialog] = useState(false);
  const [unlockItemId, setUnlockItemId] = useState<string | null>(null);

  // Filter files based on search query
  const filteredFiles = useMemo(() => {
    if (!searchQuery.trim()) return files;
    const query = searchQuery.toLowerCase();
    return files.filter(
      (file) =>
        file.name.toLowerCase().includes(query) ||
        (file.type === 'file' && file.content?.toLowerCase().includes(query))
    );
  }, [files, searchQuery]);

  // Group files by folder
  const groupedFiles = useMemo(() => {
    const folders: FileNode[] = [];
    const rootFiles: FileNode[] = [];

    filteredFiles.forEach((file) => {
      if (file.type === 'folder') {
        folders.push(file);
      } else if (!file.parentId) {
        rootFiles.push(file);
      }
    });

    return { folders, rootFiles };
  }, [filteredFiles]);

  const handleItemClick = useCallback(
    (item: FileNode) => {
      if (item.type === 'folder') {
        const isSecure = isSecureItem(item, files);
        if (isSecure) {
          const secureFolderId = getSecureFolderId(item, files);
          const idToCheck = secureFolderId || item.id;
          if (!isUnlocked(idToCheck)) {
            setUnlockItemId(idToCheck);
            setShowUnlockDialog(true);
            return;
          }
        }
        updateFile(item.id, { isExpanded: !item.isExpanded });
      } else {
        secureOpenFile(item.id);
      }
    },
    [files, isUnlocked, updateFile, secureOpenFile]
  );

  const handleEdit = useCallback(
    (item: FileNode) => {
      if (item.type === 'file') {
        secureOpenFile(item.id);
      } else {
        // For folders, we could open rename dialog or similar
        toast.info('Folder editing not available');
      }
    },
    [secureOpenFile]
  );

  const handleDelete = useCallback((item: FileNode) => {
    const isSecure = isSecureItem(item, files);
    if (isSecure) {
      const secureFolderId = getSecureFolderId(item, files);
      const idToCheck = secureFolderId || item.id;
      if (!isUnlocked(idToCheck)) {
        toast.error('Cannot delete locked secure item');
        return;
      }
    }
    setItemToDelete(item.id);
    setDeleteConfirmOpen(true);
  }, [files, isUnlocked]);

  const confirmDelete = useCallback(async () => {
    if (itemToDelete) {
      try {
        await deleteFile(itemToDelete);
        toast.success('Item moved to trash');
        setItemToDelete(null);
        setDeleteConfirmOpen(false);
      } catch (error) {
        toast.error('Failed to delete item');
      }
    }
  }, [itemToDelete, deleteFile]);

  // Sidemenu: only root-level Secure Notes folder not editable; items inside show options when unlocked
  const canRenameOrDelete = (item: FileNode, isSecure: boolean, isUnlockedItem: boolean) => {
    const isRootSecureFolder = item.secure && item.type === 'folder' && (item.parentId == null || item.parentId === '');
    return !isRootSecureFolder && (!isSecure || isUnlockedItem);
  };

  const renderGridItem = (item: FileNode) => {
    const isSecure = isSecureItem(item, files);
    const secureFolderId = getSecureFolderId(item, files);
    const idToCheck = secureFolderId || item.id;
    const isUnlockedItem = !isSecure || isUnlocked(idToCheck);
    const canEditOrDelete = canRenameOrDelete(item, isSecure, isUnlockedItem);
    const isSelected = selectedItem === item.id;

    return (
      <motion.div
        key={item.id}
        {...appleListItem}
        transition={appleSpringGentle}
        className={`group relative p-4 rounded-lg border-2 cursor-pointer transition-all ${
          isSelected
            ? 'border-primary bg-primary/10'
            : 'border-transparent hover:border-sidebar-border hover:bg-sidebar-accent'
        }`}
        onClick={() => {
          setSelectedItem(item.id);
          handleItemClick(item);
        }}
      >
        <div className="flex flex-col items-center gap-2">
          <div className="relative">
            {item.type === 'folder' ? (
              item.isExpanded ? (
                <FolderOpen className="w-12 h-12 text-primary" />
              ) : (
                <Folder className="w-12 h-12 text-primary" />
              )
            ) : (
              <FileIcon fileName={item.name} size={48} />
            )}
            {isSecure && (
              <div className="absolute -top-1 -right-1">
                {isUnlockedItem ? (
                  <LockOpen className="w-4 h-4 text-primary/60" />
                ) : (
                  <Lock className="w-4 h-4 text-primary" />
                )}
              </div>
            )}
          </div>
          <div className="text-center w-full">
            <p className="text-sm font-medium truncate">{item.name}</p>
            {item.type === 'file' && item.language && (
              <p className="text-xs text-muted-foreground">{item.language}</p>
            )}
          </div>
        </div>
        <div className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" size="icon" className="h-6 w-6">
                <MoreVertical className="w-3 h-3" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              {canEditOrDelete && (
                <DropdownMenuItem onClick={() => handleEdit(item)}>
                  <Edit2 className="w-3 h-3 mr-2" /> Edit
                </DropdownMenuItem>
              )}
              {isSecure && isUnlockedItem && (
                <DropdownMenuItem onClick={() => lockItem(idToCheck)}>
                  <Lock className="w-3 h-3 mr-2" /> Lock
                </DropdownMenuItem>
              )}
              {canEditOrDelete && (
                <>
                  <DropdownMenuSeparator />
                  <DropdownMenuItem
                    onClick={() => handleDelete(item)}
                    className="text-destructive"
                  >
                    <Trash2 className="w-3 h-3 mr-2" /> Delete
                  </DropdownMenuItem>
                </>
              )}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </motion.div>
    );
  };

  const renderListItem = (item: FileNode) => {
    const isSecure = isSecureItem(item, files);
    const secureFolderId = getSecureFolderId(item, files);
    const idToCheck = secureFolderId || item.id;
    const isUnlockedItem = !isSecure || isUnlocked(idToCheck);
    const canEditOrDelete = canRenameOrDelete(item, isSecure, isUnlockedItem);
    const isSelected = selectedItem === item.id;

    return (
      <motion.div
        key={item.id}
        {...appleListItem}
        transition={appleSpringGentle}
        className={`group flex items-center gap-3 px-3 py-2 rounded-lg cursor-pointer transition-colors ${
          isSelected
            ? 'bg-primary/10 text-primary'
            : 'hover:bg-sidebar-accent'
        }`}
        onClick={() => {
          setSelectedItem(item.id);
          handleItemClick(item);
        }}
      >
        <div className="flex-shrink-0">
          {item.type === 'folder' ? (
            item.isExpanded ? (
              <FolderOpen className="w-5 h-5 text-primary" />
            ) : (
              <Folder className="w-5 h-5 text-primary" />
            )
          ) : (
            <FileIcon fileName={item.name} size={20} />
          )}
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <p className="text-sm font-medium truncate">{item.name}</p>
            {isSecure && (
              <div>
                {isUnlockedItem ? (
                  <LockOpen className="w-3 h-3 text-primary/60" />
                ) : (
                  <Lock className="w-3 h-3 text-primary" />
                )}
              </div>
            )}
          </div>
          {item.type === 'file' && item.language && (
            <p className="text-xs text-muted-foreground">{item.language}</p>
          )}
        </div>
        <div className="flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" size="icon" className="h-7 w-7">
                <MoreVertical className="w-4 h-4" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              {canEditOrDelete && (
                <DropdownMenuItem onClick={() => handleEdit(item)}>
                  <Edit2 className="w-3 h-3 mr-2" /> Edit
                </DropdownMenuItem>
              )}
              {isSecure && isUnlockedItem && (
                <DropdownMenuItem onClick={() => lockItem(idToCheck)}>
                  <Lock className="w-3 h-3 mr-2" /> Lock
                </DropdownMenuItem>
              )}
              {canEditOrDelete && (
                <>
                  <DropdownMenuSeparator />
                  <DropdownMenuItem
                    onClick={() => handleDelete(item)}
                    className="text-destructive"
                  >
                    <Trash2 className="w-3 h-3 mr-2" /> Delete
                  </DropdownMenuItem>
                </>
              )}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </motion.div>
    );
  };

  return (
    <div className="h-full flex flex-col">
      {/* Header with search and view controls */}
      <div className="flex items-center gap-2 px-3 py-2 border-b border-sidebar-border">
        <div className="relative flex-1">
          <Search className="absolute left-2 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
          <Input
            placeholder="Search files..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="pl-8 h-8 text-xs"
          />
        </div>
        <div className="flex gap-1">
          <Button
            variant={viewMode === 'grid' ? 'default' : 'ghost'}
            size="icon"
            className="h-8 w-8"
            onClick={() => setViewMode('grid')}
          >
            <Grid3x3 className="w-4 h-4" />
          </Button>
          <Button
            variant={viewMode === 'list' ? 'default' : 'ghost'}
            size="icon"
            className="h-8 w-8"
            onClick={() => setViewMode('list')}
          >
            <List className="w-4 h-4" />
          </Button>
        </div>
      </div>

      {/* Content area */}
      <div className="flex-1 overflow-auto apple-scroll p-4">
        {filteredFiles.length === 0 ? (
          <div className="flex flex-col items-center justify-center h-full text-center text-muted-foreground">
            <File className="w-12 h-12 mb-4 opacity-30" />
            <p className="text-sm">
              {searchQuery ? 'No files found' : 'No files available'}
            </p>
          </div>
        ) : viewMode === 'grid' ? (
          <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
            {[...groupedFiles.folders, ...groupedFiles.rootFiles].map((item) =>
              renderGridItem(item)
            )}
          </div>
        ) : (
          <div className="space-y-1">
            {[...groupedFiles.folders, ...groupedFiles.rootFiles].map((item) =>
              renderListItem(item)
            )}
          </div>
        )}
      </div>

      {/* Delete Confirmation Dialog */}
      <AlertDialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete Item?</AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to delete this item? It will be moved to trash.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              onClick={confirmDelete}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* Unlock Dialog */}
      {showUnlockDialog && unlockItemId && (
        <SecureUnlockDialog
          open={showUnlockDialog}
          onOpenChange={setShowUnlockDialog}
          itemId={unlockItemId}
          itemName={
            files.find((f) => f.id === unlockItemId)?.name || 'Secure Item'
          }
          itemType={
            files.find((f) => f.id === unlockItemId)?.type === 'folder'
              ? 'folder'
              : 'file'
          }
          onUnlocked={() => {
            setShowUnlockDialog(false);
            setUnlockItemId(null);
          }}
        />
      )}

      {UnlockDialog}
    </div>
  );
};

export default FileManager;
