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,
  X,
  Plus,
} 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 { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  Dialog,
  DialogContent,
  DialogOverlay,
} from '@/components/ui/dialog';
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, LanguageMode } from '@/core/types';
import { getLanguageFromFileName } from '@/editor/languages';

type ViewMode = 'grid' | 'list';

export const FileManagerModal: React.FC = () => {
  const { files, deleteFile, updateFile, addFile, isFileManagerOpen, setFileManagerOpen } = 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);
  const [isCreating, setIsCreating] = useState<'file' | 'folder' | null>(null);
  const [createName, setCreateName] = useState('');
  const [isRenaming, setIsRenaming] = useState(false);
  const [renameItem, setRenameItem] = useState<FileNode | null>(null);
  const [renameValue, setRenameValue] = useState('');

  // 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);
        setFileManagerOpen(false); // Close modal when opening file
      }
    },
    [files, isUnlocked, updateFile, secureOpenFile, setFileManagerOpen]
  );

  const handleEdit = useCallback(
    (item: FileNode) => {
      if (item.type === 'file') {
        secureOpenFile(item.id);
        setFileManagerOpen(false); // Close modal when opening file
      } else {
        // Start renaming folder
        setRenameItem(item);
        setRenameValue(item.name);
        setIsRenaming(true);
      }
    },
    [secureOpenFile, setFileManagerOpen]
  );

  const handleRename = useCallback(async () => {
    if (renameItem && renameValue.trim() && renameValue !== renameItem.name) {
      try {
        await updateFile(renameItem.id, { name: renameValue.trim() });
        toast.success('Renamed successfully');
        setIsRenaming(false);
        setRenameItem(null);
        setRenameValue('');
      } catch (error) {
        console.error('Failed to rename:', error);
        toast.error('Failed to rename');
      }
    } else {
      setIsRenaming(false);
      setRenameItem(null);
      setRenameValue('');
    }
  }, [renameItem, renameValue, updateFile]);

  const handleCreate = useCallback(async () => {
    if (createName.trim() && isCreating) {
      try {
        await addFile({
          name: createName.trim(),
          type: isCreating,
          parentId: null, // Create at root level
          language: isCreating === 'file' ? (getLanguageFromFileName(createName.trim()) as LanguageMode) : undefined,
          content: isCreating === 'file' ? '' : undefined,
          isExpanded: isCreating === 'folder' ? true : undefined,
        });
        toast.success(`${isCreating === 'file' ? 'File' : 'Folder'} created successfully`);
        setIsCreating(null);
        setCreateName('');
      } catch (error) {
        console.error('Failed to create:', error);
        toast.error('Failed to create');
      }
    } else {
      setIsCreating(null);
      setCreateName('');
    }
  }, [createName, isCreating, addFile]);

  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]);

  // 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 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]);

  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-muted-foreground" />
              )
            ) : (
              <File className="w-12 h-12 text-muted-foreground" />
            )}
            {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={() => {
                  if (item.type === 'file') {
                    handleEdit(item);
                  } else {
                    setRenameItem(item);
                    setRenameValue(item.name);
                    setIsRenaming(true);
                  }
                }}>
                  <Edit2 className="w-3 h-3 mr-2" /> {item.type === 'file' ? 'Edit' : 'Rename'}
                </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-muted-foreground" />
            )
          ) : (
            <File className="w-5 h-5 text-muted-foreground" />
          )}
        </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={() => {
                  if (item.type === 'file') {
                    handleEdit(item);
                  } else {
                    setRenameItem(item);
                    setRenameValue(item.name);
                    setIsRenaming(true);
                  }
                }}>
                  <Edit2 className="w-3 h-3 mr-2" /> {item.type === 'file' ? 'Edit' : 'Rename'}
                </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 (
    <>
      <Dialog open={isFileManagerOpen} onOpenChange={setFileManagerOpen}>
        <DialogContent className="max-w-[95vw] max-h-[95vh] w-[95vw] h-[95vh] p-0 flex flex-col [&>button]:hidden">
          {/* Header */}
          <div className="flex items-center justify-between px-6 py-4 border-b border-sidebar-border flex-shrink-0">
            <h2 className="text-xl font-semibold">File Manager</h2>
            <div className="flex items-center gap-2">
              <div className="flex gap-1">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => setIsCreating('file')}
                  className="h-9"
                >
                  <Plus className="w-4 h-4 mr-2" />
                  New File
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => setIsCreating('folder')}
                  className="h-9"
                >
                  <Plus className="w-4 h-4 mr-2" />
                  New Folder
                </Button>
              </div>
              <div className="relative flex-1 max-w-xs">
                <Search className="absolute left-3 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-10 h-9"
                />
              </div>
              <div className="flex gap-1">
                <Button
                  variant={viewMode === 'grid' ? 'default' : 'ghost'}
                  size="icon"
                  className="h-9 w-9"
                  onClick={() => setViewMode('grid')}
                >
                  <Grid3x3 className="w-4 h-4" />
                </Button>
                <Button
                  variant={viewMode === 'list' ? 'default' : 'ghost'}
                  size="icon"
                  className="h-9 w-9"
                  onClick={() => setViewMode('list')}
                >
                  <List className="w-4 h-4" />
                </Button>
              </div>
              <Button
                variant="ghost"
                size="icon"
                onClick={() => setFileManagerOpen(false)}
                className="h-8 w-8"
              >
                <X className="h-4 w-4" />
              </Button>
            </div>
          </div>

          {/* Content area */}
          <div className="flex-1 overflow-auto apple-scroll p-6">
            {/* Create new item input */}
            {isCreating && (
              <div className="mb-4 p-3 border border-primary rounded-lg bg-primary/5">
                <div className="flex items-center gap-2">
                  {isCreating === 'folder' ? (
                    <Folder className="w-4 h-4 text-primary" />
                  ) : (
                    <File className="w-4 h-4 text-muted-foreground" />
                  )}
                  <Input
                    value={createName}
                    onChange={(e) => setCreateName(e.target.value)}
                    onBlur={handleCreate}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter') handleCreate();
                      if (e.key === 'Escape') {
                        setIsCreating(null);
                        setCreateName('');
                      }
                    }}
                    placeholder={isCreating === 'folder' ? 'folder name' : 'filename.ext'}
                    className="h-8 flex-1"
                    autoFocus
                  />
                </div>
              </div>
            )}

            {/* Rename input */}
            {isRenaming && renameItem && (
              <div className="mb-4 p-3 border border-primary rounded-lg bg-primary/5">
                <div className="flex items-center gap-2">
                  {renameItem.type === 'folder' ? (
                    <Folder className="w-4 h-4 text-primary" />
                  ) : (
                    <File className="w-4 h-4 text-muted-foreground" />
                  )}
                  <Input
                    value={renameValue}
                    onChange={(e) => setRenameValue(e.target.value)}
                    onBlur={handleRename}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter') handleRename();
                      if (e.key === 'Escape') {
                        setIsRenaming(false);
                        setRenameItem(null);
                        setRenameValue('');
                      }
                    }}
                    placeholder="New name"
                    className="h-8 flex-1"
                    autoFocus
                  />
                </div>
              </div>
            )}

            {filteredFiles.length === 0 ? (
              <div className="flex flex-col items-center justify-center h-full text-center text-muted-foreground">
                <File className="w-16 h-16 mb-4 opacity-30" />
                <p className="text-base">
                  {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 xl:grid-cols-6 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>
        </DialogContent>
      </Dialog>

      {/* 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}
    </>
  );
};
