"use client";
 
import React, { useState } from 'react';
import { FileDocument, FolderDocument } from '@/types';
import { FileTreeItem } from './file-tree-item';
import { FolderTreeItem } from './folder-tree-item';
import { 
  DndContext, 
  DragEndEvent, 
  DragOverlay, 
  DragStartEvent,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
} from '@dnd-kit/core';
import {
  SortableContext,
  sortableKeyboardCoordinates,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { FileTypeDetector } from '@/lib/file-type-detector';

export interface FileTreeProps {
  files: FileDocument[];
  folders: FolderDocument[];
  selectedFileId?: string;
  selectedFolderId?: string | null;
  expandedFolders: Set<string>;
  onFileSelect: (file: FileDocument) => void;
  onFolderSelect: (folderId: string | null) => void;
  onFolderToggle: (folderId: string) => void;
  onFileDelete: (fileId: string) => void;
  onFileRename: (fileId: string, newName: string) => void;
  onFileDuplicate: (fileId: string) => void;
  onFileDrop?: (fileId: string, targetFolderId: string | null) => void;
  onFolderDrop?: (folderId: string, targetFolderId: string | null) => void;
}

interface DragItem {
  id: string;
  type: 'file' | 'folder';
  name: string;
}

export function FileTree({
  files,
  folders,
  selectedFileId,
  selectedFolderId,
  expandedFolders,
  onFileSelect,
  onFolderSelect,
  onFolderToggle,
  onFileDelete,
  onFileRename,
  onFileDuplicate,
  onFileDrop,
  onFolderDrop
}: FileTreeProps) {
  const [activeItem, setActiveItem] = useState<DragItem | null>(null);

  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 8,
      },
    }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  type TreeNode = { type: 'file' | 'folder'; item: FileDocument | FolderDocument; children?: TreeNode[] };

  // Build tree structure
  const buildTree = () => {
    const tree: TreeNode[] = [];
    
    // Add root folders first
    const rootFolders = folders.filter(folder => !folder.parentFolderId);
    
    const addFolderToTree = (folder: FolderDocument, parentArray: TreeNode[]) => {
      const folderNode = {
        type: 'folder' as const,
        item: folder,
        children: [] as TreeNode[]
      };
      
      parentArray.push(folderNode);
      
      // Add subfolders
      const subfolders = folders.filter(f => f.parentFolderId === folder._id);
      subfolders.forEach(subfolder => addFolderToTree(subfolder, folderNode.children));
      
      // Add files in this folder
      const folderFiles = files.filter(f => f.parentFolderId === folder._id);
      folderFiles.forEach(file => {
        folderNode.children.push({
          type: 'file' as const,
          item: file
        });
      });
    };
    
    // Add root folders and their contents
    rootFolders.forEach(folder => addFolderToTree(folder, tree));
    
    // Add root files (files without parent folder)
    const rootFiles = files.filter(file => !file.parentFolderId);
    rootFiles.forEach(file => {
      tree.push({
        type: 'file' as const,
        item: file
      });
    });
    
    return tree;
  };

  const tree = buildTree();

  const handleDragStart = (event: DragStartEvent) => {
    const { active } = event;
    const [type, id] = (active.id as string).split(':');
    
    let name = '';
    if (type === 'file') {
      const file = files.find(f => f._id === id);
      name = file?.name || '';
    } else if (type === 'folder') {
      const folder = folders.find(f => f._id === id);
      name = folder?.name || '';
    }
    
    setActiveItem({
      id,
      type: type as 'file' | 'folder',
      name
    });
  };

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    setActiveItem(null);
    
    if (!over) return;
    
    const [activeType, activeId] = (active.id as string).split(':');
    const [overType, overId] = (over.id as string).split(':');
    
    // Don't allow dropping on self
    if (activeId === overId) return;
    
    // Handle file drop
    if (activeType === 'file') {
      const targetFolderId = overType === 'folder' ? overId : null;
      onFileDrop?.(activeId, targetFolderId);
    }
    
    // Handle folder drop
    if (activeType === 'folder') {
      const targetFolderId = overType === 'folder' ? overId : null;
      onFolderDrop?.(activeId, targetFolderId);
    }
  };

  const renderTreeNode = (node: TreeNode, level: number = 0) => {
    const { type, item, children } = node;
    
    if (type === 'folder') {
      const folder = item as FolderDocument;
      const isExpanded = expandedFolders.has(folder._id);
      const isSelected = selectedFolderId === folder._id;
      
      return (
        <div key={folder._id}>
          <FolderTreeItem
            folder={folder}
            level={level}
            isExpanded={isExpanded}
            isSelected={isSelected}
            onToggle={() => onFolderToggle(folder._id)}
            onSelect={() => onFolderSelect(folder._id)}
            isDragOver={false} // TODO: implement drag over state
          />
          
          {isExpanded && children && children.length > 0 && (
            <div className="ml-4">
              {children.map((child: TreeNode) => renderTreeNode(child, level + 1))}
            </div>
          )}
        </div>
      );
    } else {
      const file = item as FileDocument;
      const isSelected = selectedFileId === file._id;
      
      return (
        <FileTreeItem
          key={file._id}
          file={file}
          level={level}
          isSelected={isSelected}
          onSelect={() => onFileSelect(file)}
          onDelete={() => onFileDelete(file._id)}
          onRename={(newName) => onFileRename(file._id, newName)}
          onDuplicate={() => onFileDuplicate(file._id)}
        />
      );
    }
  };

  const allItems = [
    ...folders.map(f => `folder:${f._id}`),
    ...files.map(f => `file:${f._id}`)
  ];

  if (tree.length === 0) {
    return (
      <div className="text-center text-neutral-400 py-8">
        <div className="text-sm">No files or folders</div>
        <div className="text-xs mt-1">Create your first file or folder to get started</div>
      </div>
    );
  }

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCenter}
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
    >
      <SortableContext items={allItems} strategy={verticalListSortingStrategy}>
        <div className="space-y-1">
          {tree.map(node => renderTreeNode(node))}
        </div>
      </SortableContext>
      
      <DragOverlay>
        {activeItem ? (
          <div className="bg-neutral-800 border border-neutral-600 rounded px-2 py-1 text-sm text-white shadow-lg">
            <div className="flex items-center gap-2">
              <span>
                {activeItem.type === 'file' 
                  ? FileTypeDetector.getFileIcon(
                      files.find(f => f._id === activeItem.id)?.type || 'txt'
                    )
                  : '📁'
                }
              </span>
              <span>{activeItem.name}</span>
            </div>
          </div>
        ) : null}
      </DragOverlay>
    </DndContext>
  );
}
