/**
 * FileBrowser -- Folder-tree file browser for workspace.
 *
 * Uses useFileContext() for folders (shared state with Dateien page).
 * Uses FolderTree with showFiles=true so folders and files render inline.
 */

import React, { useState, useCallback, useRef, useMemo } from 'react';
import api from '../../../api';
import FolderTree from '../../../components/FolderTree/FolderTree';
import type { FileNode } from '../../../components/FolderTree/FolderTree';
import { useFileContext } from '../../../contexts/FileContext';
import type { WorkspaceFile } from './useWorkspace';

interface FileBrowserProps {
  instanceId: string;
  files: WorkspaceFile[];
  onRefresh: () => void;
  onFileSelect?: (fileId: string) => void;
}

export const FileBrowser: React.FC<FileBrowserProps> = ({
  instanceId,
  files,
  onRefresh,
  onFileSelect,
}) => {
  const [searchQuery, setSearchQuery] = useState('');
  const [isDragOver, setIsDragOver] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [selectedFolderId, setSelectedFolderId] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const {
    folders,
    refreshFolders,
    handleCreateFolder,
    handleRenameFolder,
    handleDeleteFolder,
    handleMoveFolder,
    handleMoveFolders,
    handleMoveFile,
    handleMoveFiles: contextMoveFiles,
    handleFileDelete,
    handleDownloadFolder,
    expandedFolderIds,
    toggleFolderExpanded,
  } = useFileContext();

  const _folderNodes = useMemo(() =>
    folders.map(f => ({
      id: f.id,
      name: f.name,
      parentId: f.parentId ?? null,
    })),
    [folders],
  );

  const _fileNodes: FileNode[] = useMemo(() => {
    let result: WorkspaceFile[] = files;
    if (searchQuery.trim()) {
      const q = searchQuery.toLowerCase();
      result = result.filter(f =>
        f.fileName.toLowerCase().includes(q)
        || (f.tags || []).some((t: string) => t.toLowerCase().includes(q)),
      );
    }
    return result
      .sort((a, b) => a.fileName.localeCompare(b.fileName))
      .map(f => ({
        id: f.id,
        fileName: f.fileName,
        mimeType: f.mimeType,
        fileSize: f.fileSize,
        folderId: f.folderId ?? null,
      }));
  }, [files, searchQuery]);

  const _refreshAll = useCallback(() => {
    onRefresh();
    refreshFolders();
  }, [onRefresh, refreshFolders]);

  const _uploadFiles = useCallback(async (fileList: FileList | File[]) => {
    if (!instanceId || uploading) return;
    setUploading(true);
    try {
      for (const file of Array.from(fileList)) {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('featureInstanceId', instanceId);
        await api.post('/api/files/upload', formData, {
          headers: { 'Content-Type': 'multipart/form-data' },
        });
      }
      _refreshAll();
    } catch (err) {
      console.error('File upload failed:', err);
    } finally {
      setUploading(false);
    }
  }, [instanceId, uploading, _refreshAll]);

  const _handleDragOver = useCallback((e: React.DragEvent) => {
    if (e.dataTransfer.types.includes('Files')) {
      e.preventDefault();
      e.stopPropagation();
      setIsDragOver(true);
    }
  }, []);

  const _handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(false);
  }, []);

  const _handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(false);
    if (e.dataTransfer.files.length > 0) {
      _uploadFiles(e.dataTransfer.files);
    }
  }, [_uploadFiles]);

  const _handleFileInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      _uploadFiles(e.target.files);
      e.target.value = '';
    }
  }, [_uploadFiles]);

  const _onMoveFile = useCallback(async (fileId: string, targetFolderId: string | null) => {
    await handleMoveFile(fileId, targetFolderId);
    onRefresh();
  }, [handleMoveFile, onRefresh]);

  const _onMoveFiles = useCallback(async (fileIds: string[], targetFolderId: string | null) => {
    await contextMoveFiles(fileIds, targetFolderId);
    onRefresh();
  }, [contextMoveFiles, onRefresh]);

  const _onDeleteFolder = useCallback(async (folderId: string) => {
    await handleDeleteFolder(folderId);
    if (selectedFolderId === folderId) setSelectedFolderId(null);
    onRefresh();
  }, [handleDeleteFolder, selectedFolderId, onRefresh]);

  const _onRenameFile = useCallback(async (fileId: string, newName: string) => {
    await api.put(`/api/files/${fileId}`, { fileName: newName });
    onRefresh();
  }, [onRefresh]);

  const _onDeleteFile = useCallback(async (fileId: string) => {
    await handleFileDelete(fileId);
    onRefresh();
  }, [handleFileDelete, onRefresh]);

  const _onDeleteFiles = useCallback(async (fileIds: string[]) => {
    await api.post('/api/files/batch-delete', { fileIds });
    onRefresh();
  }, [onRefresh]);

  const _onDeleteFolders = useCallback(async (folderIds: string[]) => {
    await api.post('/api/files/batch-delete', { folderIds, recursiveFolders: true });
    refreshFolders();
    onRefresh();
  }, [refreshFolders, onRefresh]);

  return (
    <div
      style={{ padding: 8, position: 'relative', display: 'flex', flexDirection: 'column', gap: 4 }}
      onDragOver={_handleDragOver}
      onDragLeave={_handleDragLeave}
      onDrop={_handleDrop}
    >
      {isDragOver && (
        <div style={{
          position: 'absolute', inset: 0,
          background: 'rgba(25, 118, 210, 0.08)',
          border: '2px dashed #1976d2', borderRadius: 8,
          zIndex: 10, display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 13, fontWeight: 600, color: '#1976d2',
        }}>
          Dateien hier ablegen
        </div>
      )}

      {/* Header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <span style={{ fontSize: 12, fontWeight: 600, color: '#666', textTransform: 'uppercase' }}>Files</span>
        <div style={{ display: 'flex', gap: 4 }}>
          <button
            onClick={() => fileInputRef.current?.click()}
            disabled={uploading}
            style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 12, color: '#1976d2' }}
            title="Upload files"
          >
            {uploading ? '...' : '+'}
          </button>
          <button onClick={_refreshAll} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 12, color: '#1976d2' }}>{'\u21BB'}</button>
        </div>
      </div>

      <input ref={fileInputRef} type="file" multiple style={{ display: 'none' }} onChange={_handleFileInputChange} />

      {/* Search */}
      <input
        type="text"
        placeholder="Dateien suchen..."
        value={searchQuery}
        onChange={e => setSearchQuery(e.target.value)}
        style={{
          width: '100%', padding: '6px 10px', fontSize: 12, borderRadius: 4,
          border: '1px solid #ddd', boxSizing: 'border-box',
        }}
      />

      {/* Folder tree with inline files */}
      <FolderTree
        folders={_folderNodes}
        files={_fileNodes}
        showFiles={true}
        selectedFolderId={selectedFolderId}
        onSelect={setSelectedFolderId}
        onFileSelect={onFileSelect}
        expandedIds={expandedFolderIds}
        onToggleExpand={toggleFolderExpanded}
        onRefresh={_refreshAll}
        onCreateFolder={handleCreateFolder}
        onRenameFolder={handleRenameFolder}
        onDeleteFolder={_onDeleteFolder}
        onMoveFolder={handleMoveFolder}
        onMoveFolders={handleMoveFolders}
        onMoveFile={_onMoveFile}
        onMoveFiles={_onMoveFiles}
        onRenameFile={_onRenameFile}
        onDeleteFile={_onDeleteFile}
        onDeleteFiles={_onDeleteFiles}
        onDeleteFolders={_onDeleteFolders}
        onDownloadFolder={handleDownloadFolder}
      />

      {_fileNodes.length === 0 && (
        <div style={{ fontSize: 12, color: '#999', textAlign: 'center', padding: 16 }}>
          {searchQuery ? 'Keine Dateien gefunden' : 'Keine Dateien. Drag & Drop zum Hochladen.'}
        </div>
      )}
    </div>
  );
};
