/**
 * FileBrowser -- Tree-structured file browser.
 *
 * Level 1: Feature instance (group header, collapsible)
 * Level 2: Files sorted alphabetically
 *
 * Supports search, drag-and-drop upload, and file selection.
 */

import React, { useState, useCallback, useRef, useMemo } from 'react';
import api from '../../../api';
import type { WorkspaceFile, WorkspaceFolder } from './useWorkspace';

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

interface _InstanceGroup {
  instanceId: string;
  label: string;
  files: WorkspaceFile[];
}

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

  const _filteredFiles = useMemo(() => {
    if (!searchQuery.trim()) return files;
    const q = searchQuery.toLowerCase();
    return files.filter(f =>
      f.fileName.toLowerCase().includes(q)
      || (f.tags || []).some(t => t.toLowerCase().includes(q)),
    );
  }, [files, searchQuery]);

  const _groups = useMemo((): _InstanceGroup[] => {
    const map: Record<string, _InstanceGroup> = {};
    for (const f of _filteredFiles) {
      const key = f.featureInstanceId || '_workspace';
      if (!map[key]) {
        map[key] = {
          instanceId: key,
          label: f.featureInstanceLabel || (key === '_workspace' ? 'Workspace' : key.slice(0, 8)),
          files: [],
        };
      }
      map[key].files.push(f);
    }
    for (const g of Object.values(map)) {
      g.files.sort((a, b) => a.fileName.localeCompare(b.fileName));
    }
    const groups = Object.values(map);
    groups.sort((a, b) => a.label.localeCompare(b.label));
    return groups;
  }, [_filteredFiles]);

  const _toggleGroup = (key: string) => {
    setCollapsed(prev => ({ ...prev, [key]: !prev[key] }));
  };

  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' },
        });
      }
      onRefresh();
    } catch (err) {
      console.error('File upload failed:', err);
    } finally {
      setUploading(false);
    }
  }, [instanceId, uploading, onRefresh]);

  const _handleDragOver = useCallback((e: React.DragEvent) => {
    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]);

  return (
    <div
      style={{ padding: 8, position: 'relative' }}
      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', marginBottom: 8 }}>
        <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={onRefresh} 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', marginBottom: 8, boxSizing: 'border-box',
        }}
      />

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

      {_groups.map(group => {
        const isCollapsed = !!collapsed[group.instanceId];
        return (
          <div key={group.instanceId} style={{ marginBottom: 4 }}>
            {/* Group header */}
            <div
              onClick={() => _toggleGroup(group.instanceId)}
              style={{
                display: 'flex', alignItems: 'center', gap: 6,
                padding: '5px 6px', cursor: 'pointer', borderRadius: 4,
                background: 'var(--bg-secondary, #f5f5f5)',
                marginBottom: 2,
              }}
              onMouseEnter={e => (e.currentTarget.style.background = '#eee')}
              onMouseLeave={e => (e.currentTarget.style.background = 'var(--bg-secondary, #f5f5f5)')}
            >
              <span style={{ fontSize: 10, color: '#888', width: 12, textAlign: 'center' }}>
                {isCollapsed ? '\u25B6' : '\u25BC'}
              </span>
              <span style={{ fontSize: 12 }}>{'\uD83D\uDCC1'}</span>
              <span style={{ fontSize: 12, fontWeight: 600, flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {group.label}
              </span>
              <span style={{ fontSize: 10, color: '#aaa', flexShrink: 0 }}>{group.files.length}</span>
            </div>

            {/* Files */}
            {!isCollapsed && group.files.map(file => (
              <div
                key={file.id}
                onClick={() => onFileSelect?.(file.id)}
                style={{
                  padding: '4px 8px 4px 28px', fontSize: 12,
                  display: 'flex', alignItems: 'center', gap: 6,
                  borderRadius: 4,
                  cursor: onFileSelect ? 'pointer' : 'default',
                }}
                onMouseEnter={e => (e.currentTarget.style.background = '#f5f5f5')}
                onMouseLeave={e => (e.currentTarget.style.background = '')}
              >
                <span style={{ fontSize: 11, flexShrink: 0 }}>{_fileIcon(file.mimeType)}</span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    {file.fileName}
                  </div>
                  {file.tags && file.tags.length > 0 && (
                    <div style={{ display: 'flex', gap: 3, marginTop: 2 }}>
                      {file.tags.map(tag => (
                        <span key={tag} style={{ fontSize: 9, padding: '1px 5px', borderRadius: 3, background: '#e3f2fd', color: '#1565c0' }}>
                          {tag}
                        </span>
                      ))}
                    </div>
                  )}
                </div>
                <span style={{ fontSize: 10, color: '#999', flexShrink: 0 }}>
                  {(file.fileSize / 1024).toFixed(0)}K
                </span>
              </div>
            ))}
          </div>
        );
      })}
    </div>
  );
};

function _fileIcon(mime: string): string {
  if (!mime) return '\uD83D\uDCC4';
  if (mime.startsWith('image/')) return '\uD83D\uDDBC\uFE0F';
  if (mime.includes('pdf')) return '\uD83D\uDCD5';
  if (mime.includes('word') || mime.includes('docx')) return '\uD83D\uDCD8';
  if (mime.includes('sheet') || mime.includes('xlsx') || mime.includes('csv')) return '\uD83D\uDCCA';
  if (mime.includes('presentation') || mime.includes('pptx')) return '\uD83D\uDCD9';
  if (mime.includes('zip') || mime.includes('tar') || mime.includes('gz')) return '\uD83D\uDCE6';
  if (mime.startsWith('text/') || mime.includes('json') || mime.includes('xml')) return '\uD83D\uDCDD';
  if (mime.startsWith('audio/')) return '\uD83C\uDFB5';
  if (mime.startsWith('video/')) return '\uD83C\uDFA5';
  return '\uD83D\uDCC4';
}
