import React, { useMemo, ReactElement } from 'react';
import { TechnicalTerm } from '../types';

interface Props {
  text: string;
  bionicEnabled?: boolean;
  highlightTerms?: TechnicalTerm[];
  currentTTSWord?: number; // Index of word being spoken for TTS highlighting
}

// Color palette for consistent term highlighting
const TERM_COLORS = [
  'bg-blue-100 dark:bg-blue-900/40 text-blue-800 dark:text-blue-200',
  'bg-purple-100 dark:bg-purple-900/40 text-purple-800 dark:text-purple-200',
  'bg-emerald-100 dark:bg-emerald-900/40 text-emerald-800 dark:text-emerald-200',
  'bg-amber-100 dark:bg-amber-900/40 text-amber-800 dark:text-amber-200',
  'bg-rose-100 dark:bg-rose-900/40 text-rose-800 dark:text-rose-200',
  'bg-cyan-100 dark:bg-cyan-900/40 text-cyan-800 dark:text-cyan-200',
  'bg-indigo-100 dark:bg-indigo-900/40 text-indigo-800 dark:text-indigo-200',
  'bg-teal-100 dark:bg-teal-900/40 text-teal-800 dark:text-teal-200',
];

/**
 * Apply Bionic Reading formatting to a word
 * Bold the first portion of each word based on length
 */
const applyBionicReading = (word: string): ReactElement => {
  if (word.length <= 1) return <>{word}</>;
  
  // Calculate how many letters to bold
  // Short words (1-3): 1 letter
  // Medium words (4-6): 2 letters
  // Longer words (7+): ~40% of the word
  let boldCount: number;
  if (word.length <= 3) {
    boldCount = 1;
  } else if (word.length <= 6) {
    boldCount = 2;
  } else {
    boldCount = Math.ceil(word.length * 0.4);
  }
  
  const boldPart = word.slice(0, boldCount);
  const normalPart = word.slice(boldCount);
  
  return (
    <>
      <span className="font-bold">{boldPart}</span>
      <span className="font-normal opacity-80">{normalPart}</span>
    </>
  );
};

/**
 * Check if a word matches a technical term (case-insensitive)
 */
const findMatchingTerm = (
  word: string, 
  terms: TechnicalTerm[]
): { term: TechnicalTerm; colorClass: string } | null => {
  const cleanWord = word.toLowerCase().replace(/[^a-z0-9]/g, '');
  
  for (let i = 0; i < terms.length; i++) {
    const termLower = terms[i].term.toLowerCase();
    if (cleanWord === termLower || cleanWord.includes(termLower)) {
      return {
        term: terms[i],
        colorClass: terms[i].highlightColor || TERM_COLORS[i % TERM_COLORS.length]
      };
    }
  }
  return null;
};

const BionicText: React.FC<Props> = ({ 
  text, 
  bionicEnabled = false, 
  highlightTerms = [],
  currentTTSWord 
}) => {
  const processedContent = useMemo(() => {
    // Split text into words while preserving whitespace and punctuation
    const words = text.split(/(\s+)/);
    let wordIndex = 0;
    
    return words.map((segment, idx) => {
      // If it's whitespace, just return it
      if (/^\s+$/.test(segment)) {
        return <span key={idx}>{segment}</span>;
      }
      
      const currentWordIdx = wordIndex;
      wordIndex++;
      
      // Check if this word is currently being spoken (TTS)
      const isTTSActive = currentTTSWord !== undefined && currentWordIdx === currentTTSWord;
      
      // Check if this word matches a technical term
      const matchingTerm = highlightTerms.length > 0 
        ? findMatchingTerm(segment, highlightTerms) 
        : null;
      
      // Base styling
      let className = '';
      let content: ReactElement | string = segment;
      
      // Apply TTS highlighting (karaoke style)
      if (isTTSActive) {
        className = 'bg-brand-200 dark:bg-brand-700 px-1 rounded transition-colors duration-150';
      }
      
      // Apply term highlighting
      if (matchingTerm) {
        className = `${matchingTerm.colorClass} px-1 py-0.5 rounded cursor-help transition-colors`;
      }
      
      // Apply bionic reading
      if (bionicEnabled) {
        content = applyBionicReading(segment);
      }
      
      // If it's a technical term, wrap with tooltip
      if (matchingTerm) {
        return (
          <span 
            key={idx}
            className={`inline-block ${className} group relative`}
            title={matchingTerm.term.definition}
          >
            {content}
            {/* Inline tooltip on hover */}
            <span className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-2 bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-xs rounded-lg opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none whitespace-nowrap max-w-xs z-50 shadow-lg">
              <span className="font-bold">{matchingTerm.term.term}:</span>{' '}
              {matchingTerm.term.definition}
            </span>
          </span>
        );
      }
      
      return (
        <span key={idx} className={className}>
          {content}
        </span>
      );
    });
  }, [text, bionicEnabled, highlightTerms, currentTTSWord]);

  return <span className="bionic-text">{processedContent}</span>;
};

/**
 * Hook for processing markdown content with bionic reading
 */
export const useBionicMarkdown = (content: string, enabled: boolean): string => {
  return useMemo(() => {
    if (!enabled) return content;
    
    // Process markdown while preserving syntax
    // We'll bold the first letters of words that aren't part of markdown syntax
    return content.replace(
      /(?<![#*_`\[\]])(\b\w{2,}\b)(?![#*_`\[\]])/g,
      (match) => {
        const boldCount = match.length <= 3 ? 1 : match.length <= 6 ? 2 : Math.ceil(match.length * 0.4);
        return `**${match.slice(0, boldCount)}**${match.slice(boldCount)}`;
      }
    );
  }, [content, enabled]);
};

export default BionicText;
