import { timeHourMinute } from './time';

/**
 * Processes selected text from the chat timeline and formats it as:
 * "Username - Time: Message"
 * 
 * This intercepts the copy event on the timeline and reformats the copied text.
 */
export const setupCopyHandler = (
  containerRef: React.RefObject<HTMLElement>,
  getMessageData: (eventId: string) => { sender: string; ts: number; content: string } | null,
  hour24Clock: boolean
): (() => void) => {
  const container = containerRef.current;
  if (!container) return () => {};

  const handleCopy = (event: ClipboardEvent) => {
    const selection = window.getSelection();
    if (!selection || selection.isCollapsed) return;

    const range = selection.getRangeAt(0);
    const selectedContainer = range.commonAncestorContainer;
    
    // Only process if selection is within our container
    if (!container.contains(selectedContainer)) return;

    // Find all message elements within the selection
    const messages: Array<{ sender: string; time: string; content: string }> = [];
    
    // Get all message elements in the container
    const messageElements = Array.from(container.querySelectorAll('[data-message-id]'));
    
    messageElements.forEach((msgEl) => {
      const eventId = msgEl.getAttribute('data-message-id');
      if (!eventId) return;

      const data = getMessageData(eventId);
      if (!data) return;

      // Find content elements within the message (skip headers, timestamps, etc.)
      const contentEl = msgEl.querySelector('[class*="MessageTextBody"], [class*="message-content"], [class*="MessageBody"]') as HTMLElement;
      
      if (!contentEl) return;

      // Check if the content element intersects with the selection
      // by checking if selection contains any part of it
      let isSelected = false;
      try {
        // Try to detect if this node or its children are in the selection
        const walker = document.createTreeWalker(
          contentEl,
          NodeFilter.SHOW_TEXT,
          null
        );
        
        let textNode = walker.nextNode();
        while (textNode && !isSelected) {
          if (range.intersectsNode(textNode)) {
            isSelected = true;
          }
          textNode = walker.nextNode();
        }
      } catch (e) {
        // Fallback: check if selection contains the content element
        isSelected = selection.containsNode(contentEl, true);
      }

      if (!isSelected) return;

      // Format the time
      const timeStr = timeHourMinute(data.ts, hour24Clock);
      
      // Extract the selected text from within this message's content
      let selectedText = '';
      
      // Create a range for this message's content
      const contentRange = document.createRange();
      contentRange.selectNodeContents(contentEl);
      
      // Clone the selection range to avoid modifying it
      const extractRange = range.cloneRange();
      
      // Constrain the extract range to be within the content element
      // If selection starts before content, move start to content start
      if (contentRange.compareBoundaryPoints(Range.START_TO_START, extractRange) > 0) {
        extractRange.setStart(contentRange.startContainer, contentRange.startOffset);
      }
      // If selection ends after content, move end to content end
      if (contentRange.compareBoundaryPoints(Range.END_TO_END, extractRange) < 0) {
        extractRange.setEnd(contentRange.endContainer, contentRange.endOffset);
      }
      
      selectedText = extractRange.toString().trim();
      
      if (selectedText) {
        messages.push({
          sender: data.sender,
          time: timeStr,
          content: selectedText,
        });
      }
    });

    // If we found formatted messages, use our format
    if (messages.length > 0) {
      const formattedText = messages
        .map((msg) => `${msg.sender} - ${msg.time}: ${msg.content}`)
        .join('\n');
      
      event.preventDefault();
      event.clipboardData?.setData('text/plain', formattedText);
    }
  };

  container.addEventListener('copy', handleCopy);
  return () => container.removeEventListener('copy', handleCopy);
};
