import React, { useMemo } from 'react';
import { 
  ViewActionButton, 
  DeleteActionButton, 
  RemoveActionButton,
  EditActionButton,
  CopyActionButton,
  CustomActionButton
} from '../../FormGenerator/ActionButtons';
import { FaDownload, FaLink, FaPlay } from 'react-icons/fa';
import { WorkflowFile } from '../../../hooks/usePlayground';
import styles from './ConnectedFilesList.module.css';

export interface ConnectedFilesListActionButton {
  type: 'edit' | 'delete' | 'download' | 'view' | 'copy' | 'connect' | 'play' | 'remove';
  onAction?: (file: WorkflowFile) => Promise<void> | void;
  disabled?: (file: WorkflowFile) => boolean | { disabled: boolean; message?: string };
  loading?: (file: WorkflowFile) => boolean;
  title?: string | ((file: WorkflowFile) => string);
  className?: string;
  // For download and view buttons
  isProcessing?: (file: WorkflowFile) => boolean;
  // Field mappings for flexible data access
  idField?: string; // Field name for the unique identifier (default: 'fileId')
  nameField?: string; // Field name for display name (default: 'fileName')
  typeField?: string; // Field name for type/mime type (default: 'mimeType')
  contentField?: string; // Field name for content (used by copy button)
  statusField?: string; // Field name for status (used by connect button)
  authorityField?: string; // Field name for authority (msft/google) (used by connect button)
  // Operation and loading state names
  operationName?: string; // Name of the operation function in hookData
  refreshOperationName?: string; // Name of the refresh operation function in hookData (for connect button)
  loadingStateName?: string; // Name of the loading state in hookData
  // Navigation (for play button)
  navigateTo?: string; // Route to navigate to when play button is clicked
  // Special handling for remove button
  showOnlyForPending?: boolean; // Show remove button only for pending files (default: true for 'remove' type)
}

export interface ConnectedFilesListProps {
  files: WorkflowFile[];
  pendingFiles?: WorkflowFile[];
  // New: Configurable action buttons (takes precedence over legacy props)
  actionButtons?: ConnectedFilesListActionButton[];
  // Legacy props (kept for backward compatibility, used as defaults if actionButtons not provided)
  onDelete?: (file: WorkflowFile) => Promise<void>;
  onRemove?: (file: WorkflowFile) => Promise<void>;
  onAttach?: (fileId: string) => Promise<void>; // Attach file for next message
  deletingFiles?: Set<string>;
  previewingFiles?: Set<string>;
  removingFiles?: Set<string>;
  workflowId?: string;
  emptyMessage?: string;
}

export function ConnectedFilesList({
  files,
  pendingFiles = [],
  actionButtons,
  onDelete,
  onRemove,
  onAttach,
  deletingFiles = new Set(),
  previewingFiles = new Set(),
  removingFiles = new Set(),
  workflowId: _workflowId,
  emptyMessage = 'No files connected to this workflow'
}: ConnectedFilesListProps) {
  // Combine workflow files and pending files, deduplicating by fileId
  const allFiles = useMemo(() => {
    const fileMap = new Map<string, WorkflowFile>();
    
    // Add workflow files first (filter out files without fileId)
    files.forEach(file => {
      if (file.fileId && file.fileId.trim() !== '') {
        fileMap.set(file.fileId, file);
      }
    });
    
    // Add pending files (may override workflow files if same fileId)
    pendingFiles.forEach(file => {
      if (file.fileId && file.fileId.trim() !== '') {
        fileMap.set(file.fileId, file);
      }
    });
    
    return Array.from(fileMap.values());
  }, [files, pendingFiles]);

  // Create hookData object for action buttons
  const hookData = useMemo(() => ({
    handleDelete: async (fileId: string) => {
      const file = allFiles.find(f => f.fileId === fileId);
      if (file && onDelete) {
        await onDelete(file);
        return true;
      }
      return false;
    },
    removeOptimistically: (_fileId: string) => {
      // This will be handled by the parent component's state
    },
    refetch: async () => {
      // Refetch handled by parent
    },
    deletingItems: deletingFiles,
    previewingFiles: previewingFiles,
    removingItems: removingFiles
  }), [allFiles, onDelete, deletingFiles, previewingFiles, removingFiles]);

  // Generate default action buttons from legacy props if actionButtons not provided
  const defaultActionButtons = useMemo<ConnectedFilesListActionButton[]>(() => {
    if (actionButtons) {
      return actionButtons;
    }
    
    // Legacy behavior: create default buttons from old props
    const buttons: ConnectedFilesListActionButton[] = [];
    
    // View button (always shown)
    buttons.push({
      type: 'view',
      onAction: async (_file: WorkflowFile) => {
        // View is handled by ViewActionButton's FilePreview component
        return Promise.resolve();
      },
      idField: 'fileId',
      nameField: 'fileName',
      typeField: 'mimeType'
    });
    
    // Remove button (only for pending files, if onRemove provided)
    if (onRemove) {
      buttons.push({
        type: 'remove',
        onAction: async (file: WorkflowFile) => {
          await onRemove(file);
        },
        showOnlyForPending: true,
        idField: 'fileId',
        loadingStateName: 'removingItems'
      });
    }
    
    // Delete button (always shown, if onDelete provided)
    if (onDelete) {
      buttons.push({
        type: 'delete',
        operationName: 'handleDelete',
        loadingStateName: 'deletingItems',
        idField: 'fileId'
      });
    }
    
    return buttons;
  }, [actionButtons, onDelete, onRemove]);

  const handleView = async (_file: WorkflowFile) => {
    // View is handled by ViewActionButton's FilePreview component
    return Promise.resolve();
  };

  const handleRemove = async (file: WorkflowFile) => {
    // Remove file from workflow (not delete from backend)
    if (onRemove) {
      await onRemove(file);
    }
  };

  if (allFiles.length === 0) {
    return (
      <div className={styles.container}>
        <div className={styles.emptyState}>
          {emptyMessage}
        </div>
      </div>
    );
  }

  return (
    <div className={styles.container}>
      <div className={styles.header}>
        <h3 className={styles.title}>Connected Files</h3>
        <span className={styles.count}>({allFiles.length})</span>
      </div>
      <div className={styles.fileList}>
        {allFiles
          .filter(file => file.fileId && file.fileId.trim() !== '') // Ensure fileId exists
          .map((file) => {
            // const isDeleting = deletingFiles.has(file.fileId!);
            // const isPreviewing = previewingFiles.has(file.fileId!);
            // const isRemoving = removingFiles.has(file.fileId!);
            // Use fileId as key since we've filtered out files without it
            const uniqueKey = file.fileId!;
            
            // Check if file is in pending files (can be removed) or in messages (already sent)
            const isPendingFile = pendingFiles.some(f => f.fileId === file.fileId);
            
            // Handle clicking on file item to attach/detach for next message
            const handleFileItemClick = async (e: React.MouseEvent) => {
              // Don't trigger if clicking on action buttons - they handle their own clicks
              const target = e.target as HTMLElement;
              const fileActionsElement = target.closest(`.${styles.fileActions}`);
              const buttonElement = target.closest('button');
              
              if (fileActionsElement || buttonElement) {
                e.stopPropagation();
                return;
              }
              
              // Prevent default and stop propagation to ensure click handler fires
              e.preventDefault();
              e.stopPropagation();
              
              if (onAttach && file.fileId) {
                console.log('🖱️ ConnectedFilesList: Clicking file to attach/detach:', file.fileId);
                await onAttach(file.fileId);
              }
            };
            
            return (
              <div 
                key={uniqueKey} 
                className={styles.fileItem}
                onClick={handleFileItemClick}
                style={{ 
                  cursor: onAttach ? 'pointer' : 'default',
                  userSelect: 'none' // Prevent text selection on click
                }}
                title={onAttach ? (isPendingFile ? 'Click to detach from next message' : 'Click to attach for next message') : undefined}
              >
                <div className={styles.fileInfo}>
                  <div className={styles.fileName} title={file.fileName}>
                    {file.fileName}
                    {onAttach && (
                      <span style={{ marginLeft: '0.5rem', fontSize: '0.75rem', color: '#666' }}>
                        {isPendingFile ? '(click to detach)' : '(click to attach)'}
                      </span>
                    )}
                  </div>
                  <div className={styles.fileMeta}>
                    <span className={styles.fileSize}>
                      {formatFileSize(file.fileSize)}
                    </span>
                    {file.source && (
                      <span className={styles.fileSource}>
                        {file.source === 'user_uploaded' ? 'Uploaded' : 'AI Created'}
                      </span>
                    )}
                    {isPendingFile && (
                      <span style={{ fontSize: '0.75rem', color: '#4CAF50', fontWeight: 500 }}>
                        • Attached
                      </span>
                    )}
                  </div>
                </div>
                <div className={styles.fileActions} onClick={(e) => e.stopPropagation()}>
                  {defaultActionButtons.map((actionButton, actionIndex) => {
                    // Check if button should be shown for this file
                    if (actionButton.showOnlyForPending !== undefined) {
                      const shouldShow = actionButton.showOnlyForPending ? isPendingFile : !isPendingFile;
                      if (!shouldShow) {
                        return null;
                      }
                    }
                    
                    const actionTitle = typeof actionButton.title === 'function' 
                      ? actionButton.title(file) 
                      : actionButton.title;
                    const disabledResult = actionButton.disabled ? actionButton.disabled(file) : false;
                    const isLoading = actionButton.loading ? actionButton.loading(file) : false;
                    const isProcessing = actionButton.isProcessing ? actionButton.isProcessing(file) : false;

                    const baseProps = {
                      row: file,
                      disabled: disabledResult,
                      loading: isLoading,
                      className: actionButton.className,
                      title: actionTitle,
                      idField: actionButton.idField ?? 'fileId',
                      nameField: actionButton.nameField ?? 'fileName',
                      typeField: actionButton.typeField ?? 'mimeType',
                      contentField: actionButton.contentField ?? 'content',
                      statusField: actionButton.statusField ?? 'status',
                      authorityField: actionButton.authorityField ?? 'authority',
                      operationName: actionButton.operationName,
                      refreshOperationName: actionButton.refreshOperationName,
                      loadingStateName: actionButton.loadingStateName,
                      hookData: hookData
                    };

                    switch (actionButton.type) {
                      case 'edit':
                        return <EditActionButton 
                          key={actionIndex} 
                          {...baseProps} 
                          onEdit={actionButton.onAction}
                        />;
                      case 'delete':
                        return <DeleteActionButton 
                          key={actionIndex} 
                          {...baseProps} 
                        />;
                      case 'download':
                        return <CustomActionButton 
                          key={actionIndex} 
                          row={file}
                          id="download"
                          icon={<FaDownload />}
                          onClick={actionButton.onAction || (() => {})}
                          disabled={() => disabledResult}
                          loading={() => isProcessing}
                          title={actionTitle}
                          className={actionButton.className}
                        />;
                      case 'view':
                        return <ViewActionButton 
                          key={actionIndex} 
                          {...baseProps} 
                          onView={actionButton.onAction || handleView} 
                          isViewing={isProcessing}
                        />;
                      case 'copy':
                        return <CopyActionButton 
                          key={actionIndex} 
                          {...baseProps} 
                          onCopy={actionButton.onAction} 
                          isCopying={isProcessing}
                          contentField={actionButton.contentField}
                        />;
                      case 'connect':
                        return <CustomActionButton 
                          key={actionIndex} 
                          row={file}
                          id="connect"
                          icon={<FaLink />}
                          onClick={actionButton.onAction || (() => {})}
                          disabled={() => disabledResult}
                          loading={() => isLoading}
                          title={actionTitle}
                          className={actionButton.className}
                        />;
                      case 'play':
                        return <CustomActionButton 
                          key={actionIndex} 
                          row={file}
                          id="play"
                          icon={<FaPlay />}
                          onClick={actionButton.onAction || (() => {})}
                          disabled={() => disabledResult}
                          loading={() => isLoading}
                          title={actionTitle}
                          className={actionButton.className}
                        />;
                      case 'remove':
                        return <RemoveActionButton 
                          key={actionIndex} 
                          {...baseProps} 
                          onRemove={actionButton.onAction || handleRemove}
                        />;
                      default:
                        return null;
                    }
                  })}
                </div>
              </div>
            );
          })}
      </div>
    </div>
  );
}

function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
}

export default ConnectedFilesList;

