import React from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { FaExclamationTriangle } from 'react-icons/fa';
import { Message } from '../MessagesTypes';
import { formatTimestamp } from '../MessageUtils';
import { DocumentItem, ActionInfo } from '../MessageParts';
import { WorkflowFile } from '../../../../hooks/usePlayground';
import styles from '../Messages.module.css';

export interface ChatMessageProps {
  message: Message;
  showDocuments?: boolean;
  renderDocument?: (document: any, message: Message) => React.ReactNode;
  onFileDelete?: (file: WorkflowFile) => Promise<void>;
  onFileRemove?: (file: WorkflowFile) => Promise<void>;
  onFileView?: (file: WorkflowFile) => Promise<void>;
  onFileDownload?: (file: WorkflowFile) => Promise<void>;
  deletingFiles?: Set<string>;
  previewingFiles?: Set<string>;
  removingFiles?: Set<string>;
  downloadingFiles?: Set<string>;
  workflowId?: string;
}

/**
 * Renders a single message in chat style (bubble UI)
 */
export const ChatMessage: React.FC<ChatMessageProps> = ({
  message,
  showDocuments = true,
  renderDocument,
  onFileDelete,
  onFileRemove,
  onFileView,
  onFileDownload,
  deletingFiles,
  previewingFiles,
  removingFiles,
  downloadingFiles,
  workflowId
}) => {
  const isUser = message.role?.toLowerCase() === 'user';
  const isError = message.actionProgress === 'fail' || message.actionProgress === 'error';
  const messageClass = isUser ? styles.messageUser : styles.messageAssistant;
  const errorClass = isError ? styles.messageError : '';

  return (
    <div className={`${styles.message} ${messageClass} ${errorClass}`}>
      <div className={styles.messageBubble}>
        {/* Error indicator for failed actions */}
        {isError && (
          <div className={styles.errorIndicator}>
            <FaExclamationTriangle className={styles.errorIcon} />
            <span>Aktion fehlgeschlagen</span>
          </div>
        )}
        
        {/* Message content */}
        {message.message && (
          <div className={styles.messageContent}>
            <ReactMarkdown
              remarkPlugins={[remarkGfm]}
              className={styles.markdownContent}
              components={{
                // Custom styling for markdown elements
                h1: ({node, ...props}) => <h1 className={styles.markdownH1} {...props} />,
                h2: ({node, ...props}) => <h2 className={styles.markdownH2} {...props} />,
                h3: ({node, ...props}) => <h3 className={styles.markdownH3} {...props} />,
                h4: ({node, ...props}) => <h4 className={styles.markdownH4} {...props} />,
                h5: ({node, ...props}) => <h5 className={styles.markdownH5} {...props} />,
                h6: ({node, ...props}) => <h6 className={styles.markdownH6} {...props} />,
                p: ({node, ...props}) => <p className={styles.markdownP} {...props} />,
                ul: ({node, ...props}) => <ul className={styles.markdownUl} {...props} />,
                ol: ({node, ...props}) => <ol className={styles.markdownOl} {...props} />,
                li: ({node, ...props}) => <li className={styles.markdownLi} {...props} />,
                table: ({node, ...props}) => <div className={styles.markdownTableWrapper}><table className={styles.markdownTable} {...props} /></div>,
                thead: ({node, ...props}) => <thead className={styles.markdownThead} {...props} />,
                tbody: ({node, ...props}) => <tbody className={styles.markdownTbody} {...props} />,
                tr: ({node, ...props}) => <tr className={styles.markdownTr} {...props} />,
                th: ({node, ...props}) => <th className={styles.markdownTh} data-in-table="true" {...props} />,
                td: ({node, ...props}) => <td className={styles.markdownTd} data-in-table="true" {...props} />,
                code: ({node, inline, ...props}: any) => 
                  inline ? (
                    <code className={styles.markdownCodeInline} {...props} />
                  ) : (
                    <code className={styles.markdownCodeBlock} {...props} />
                  ),
                pre: ({node, ...props}) => <pre className={styles.markdownPre} {...props} />,
                blockquote: ({node, ...props}) => <blockquote className={styles.markdownBlockquote} {...props} />,
                strong: ({node, ...props}) => <strong className={styles.markdownStrong} {...props} />,
                em: ({node, ...props}) => <em className={styles.markdownEm} {...props} />,
                a: ({node, ...props}: any) => {
                  // Check if link is inside a table by checking parent chain
                  // In react-markdown, we need to check the node structure
                  const isInTable = (node: any): boolean => {
                    let current = node.parent;
                    while (current) {
                      if (current.type === 'tableCell' || current.type === 'tableRow' || current.type === 'table') {
                        return true;
                      }
                      current = current.parent;
                    }
                    return false;
                  };
                  
                  if (isInTable(node)) {
                    // Render as plain text if inside table
                    return <span className={styles.markdownLinkText}>{props.children}</span>;
                  }
                  return <a className={styles.markdownLink} {...props} />;
                },
                hr: ({node, ...props}) => <hr className={styles.markdownHr} {...props} />,
              }}
            >
              {message.message}
            </ReactMarkdown>
          </div>
        )}
        
        {/* Summary if different from message */}
        {message.summary && message.summary !== message.message && (
          <div className={styles.messageSummary}>
            <strong>Summary:</strong> {message.summary}
          </div>
        )}
        
        {/* Documents */}
        {showDocuments && message.documents && Array.isArray(message.documents) && message.documents.length > 0 && (
          <div className={styles.documentsContainer}>
            {message.documentsLabel && (
              <div className={styles.documentsLabel}>{message.documentsLabel}</div>
            )}
            <div className={styles.documentsList}>
              {message.documents.map((doc) => (
                <div key={doc.id}>
                  {renderDocument ? renderDocument(doc, message) : (
                    <DocumentItem 
                      document={doc} 
                      message={message}
                      onFileDelete={onFileDelete}
                      onFileRemove={onFileRemove}
                      onFileView={onFileView}
                      onFileDownload={onFileDownload}
                      deletingFiles={deletingFiles}
                      previewingFiles={previewingFiles}
                      removingFiles={removingFiles}
                      downloadingFiles={downloadingFiles}
                      workflowId={workflowId}
                    />
                  )}
                </div>
              ))}
            </div>
          </div>
        )}
        
        {/* Action information (shown only for assistant messages) */}
        {!isUser && <ActionInfo message={message} />}
        
        {/* Timestamp */}
        {message.publishedAt && (
          <div className={styles.messageTimestamp}>
            {formatTimestamp(message.publishedAt)}
          </div>
        )}
      </div>
    </div>
  );
};

