import React, { useState, useCallback, useRef, useMemo, useEffect } from 'react';
import type { UdbContext } from './UnifiedDataBar';
import api from '../../api';
import FolderTree from '../../components/FolderTree/FolderTree';
import type { FileNode } from '../../components/FolderTree/FolderTree';
import { useFileContext } from '../../contexts/FileContext';
import styles from './FilesTab.module.css';

interface FileEntry {
  id: string;
  fileName: string;
  mimeType?: string;
  fileSize?: number;
  folderId?: string | null;
  tags?: string[];
  scope: string;
  neutralize: boolean;
}

interface FilesTabProps {
  context: UdbContext;
  onFileSelect?: (fileId: string, fileName?: string) => void;
}

const FilesTab: React.FC<FilesTabProps> = ({ context, onFileSelect }) => {
  const [files, setFiles] = useState<FileEntry[]>([]);
  const [loading, setLoading] = useState(true);
  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 _loadFiles = useCallback(async () => {
    setLoading(true);
    try {
      const response = await api.get(`/api/workspace/${context.instanceId}/files`);
      const body = response.data;
      const rawList =
        (Array.isArray(body?.files) && body.files) ||
        (Array.isArray(body?.data) && body.data) ||
        (Array.isArray(body) ? body : []);
      setFiles(
        rawList.map((f: any) => ({
          id: f.id,
          fileName: f.fileName || f.name || 'unknown',
          mimeType: f.mimeType,
          fileSize: f.fileSize,
          folderId: f.folderId ?? null,
          tags: f.tags || [],
          scope: f.scope || 'personal',
          neutralize: f.neutralize || false,
        })),
      );
    } catch (err) {
      console.error('Failed to load files:', err);
    } finally {
      setLoading(false);
    }
  }, [context.instanceId]);

  useEffect(() => {
    _loadFiles();
  }, [_loadFiles]);

  useEffect(() => {
    const _onFileUploaded = () => {
      setTimeout(() => _loadFiles(), 150);
    };
    window.addEventListener('fileUploaded', _onFileUploaded as EventListener);
    return () => window.removeEventListener('fileUploaded', _onFileUploaded as EventListener);
  }, [_loadFiles]);

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

  const _fileNodes: FileNode[] = useMemo(() => {
    let result = 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,
        scope: f.scope,
        neutralize: f.neutralize,
      }));
  }, [files, searchQuery]);

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

  const _uploadFiles = useCallback(async (fileList: FileList | File[]) => {
    if (!context.instanceId || uploading) return;
    setUploading(true);
    try {
      for (const file of Array.from(fileList)) {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('featureInstanceId', context.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);
    }
  }, [context.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);
    _loadFiles();
  }, [handleMoveFile, _loadFiles]);

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

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

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

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

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

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

  const _onScopeChange = useCallback(async (fileId: string, newScope: string) => {
    setFiles(prev => prev.map(f => (f.id === fileId ? { ...f, scope: newScope } : f)));
    try {
      await api.patch(`/api/files/${fileId}/scope`, { scope: newScope });
    } catch (err) {
      console.error('Failed to update scope:', err);
      _loadFiles();
    }
  }, [_loadFiles]);

  const _onNeutralizeToggle = useCallback(async (fileId: string, newValue: boolean) => {
    setFiles(prev => prev.map(f => (f.id === fileId ? { ...f, neutralize: newValue } : f)));
    try {
      await api.patch(`/api/files/${fileId}/neutralize`, { neutralize: newValue });
    } catch (err) {
      console.error('Failed to toggle neutralize:', err);
      _loadFiles();
    }
  }, [_loadFiles]);

  if (loading) return <div className={styles.loading}>Lade Dateien...</div>;

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

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '4px 8px' }}>
        <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: '#F25843' }}
            title="Upload files"
          >
            {uploading ? '...' : '+'}
          </button>
          <button
            onClick={_refreshAll}
            style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 12, color: '#F25843' }}
          >
            {'\u21BB'}
          </button>
        </div>
      </div>

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

      <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', margin: '0 0 4px',
        }}
      />

      <div style={{ flex: 1, overflow: 'auto' }}>
        <FolderTree
          folders={_folderNodes}
          files={_fileNodes}
          showFiles={true}
          selectedFolderId={selectedFolderId}
          onSelect={setSelectedFolderId}
          onFileSelect={onFileSelect ? (fileId: string) => {
            const file = files.find(f => f.id === fileId);
            onFileSelect(fileId, file?.fileName);
          } : undefined}
          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}
          onScopeChange={_onScopeChange}
          onNeutralizeToggle={_onNeutralizeToggle}
        />

        {_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>

      <div className={styles.legend}>
        <span>{'\uD83D\uDC64'} Persönlich</span>
        <span>{'\uD83D\uDC65'} Instanz</span>
        <span>{'\uD83C\uDFE2'} Mandant</span>
        <span>{'\uD83D\uDD12'} Neutralisiert</span>
      </div>
    </div>
  );
};

export default FilesTab;
