import React, { useEffect, useRef } from 'react';
import * as d3 from 'd3';
import cloud from 'd3-cloud';
import { getSimplifiedTokenizer } from '../src/browser-tokenizers';

export type Language = 'english' | 'chinese';

export interface WordCloudProps {
  /** The text to generate a word cloud from */
  text: string;
  /** The language of the text ('english' or 'chinese') */
  language: Language;
  /** Width of the word cloud in pixels */
  width?: number;
  /** Height of the word cloud in pixels */
  height?: number;
  /** Font family to use for the words */
  fontFamily?: string;
  /** Maximum number of words to include in the cloud */
  maxWords?: number;
  /** Color scheme to use for the words */
  colors?: readonly string[];
  /** Padding between words in pixels */
  padding?: number;
  /** Minimum font size for words */
  minFontSize?: number;
  /** Maximum font size for words */
  maxFontSize?: number;
  /** Rotation angles for words (in degrees) */
  rotationAngles?: number[];
  /** Probability of word rotation */
  rotationProbability?: number;
  /** Optional className for the SVG element */
  className?: string;
  /** Optional style for the SVG element */
  style?: React.CSSProperties;
}

/**
 * Default options for the word cloud
 */
const DEFAULT_OPTIONS = {
  width: 800,
  height: 600,
  fontFamily: 'Arial, sans-serif',
  maxWords: 100,
  colors: [...d3.schemeCategory10],
  padding: 5,
  minFontSize: 10,
  maxFontSize: 60,
  rotationAngles: [0, 90],
  rotationProbability: 0.3
};

/**
 * React component for generating word clouds from text
 */
export const WordCloud: React.FC<WordCloudProps> = (props) => {
  const {
    text,
    language,
    width = DEFAULT_OPTIONS.width,
    height = DEFAULT_OPTIONS.height,
    fontFamily = DEFAULT_OPTIONS.fontFamily,
    maxWords = DEFAULT_OPTIONS.maxWords,
    colors = DEFAULT_OPTIONS.colors,
    padding = DEFAULT_OPTIONS.padding,
    minFontSize = DEFAULT_OPTIONS.minFontSize,
    maxFontSize = DEFAULT_OPTIONS.maxFontSize,
    rotationAngles = DEFAULT_OPTIONS.rotationAngles,
    rotationProbability = DEFAULT_OPTIONS.rotationProbability,
    className,
    style
  } = props;

  const containerRef = useRef<SVGSVGElement>(null);

  useEffect(() => {
    if (!containerRef.current || !text) return;

    // Clear previous content
    const svg = containerRef.current;
    while (svg.firstChild) {
      svg.removeChild(svg.firstChild);
    }

    // Get the appropriate tokenizer
    const tokenizer = getSimplifiedTokenizer(language);
    
    // Tokenize the text and get word frequencies
    const wordCounts = tokenizer.tokenize(text);
    
    // Convert to array and sort by frequency
    const words = Array.from(wordCounts.entries())
      .sort((a, b) => b[1] - a[1])
      .slice(0, maxWords)
      .map(([text, size]) => {
        // Scale the font size based on frequency
        const counts = Array.from(wordCounts.values());
        const minCount = Math.min(...counts);
        const maxCount = Math.max(...counts);
        
        // Linear scaling between min and max font size
        const scaledSize = minCount === maxCount
          ? maxFontSize
          : minFontSize + 
            (size - minCount) / (maxCount - minCount) * 
            (maxFontSize - minFontSize);
        
        // Determine if word should be rotated
        const rotate = Math.random() > rotationProbability
          ? 0
          : rotationAngles[Math.floor(Math.random() * rotationAngles.length)];
        
        return {
          text,
          size: scaledSize,
          rotate
        };
      });
    
    // Generate the layout using d3-cloud
    const layout = cloud()
      .size([width, height])
      .words(words)
      .padding(padding)
      .rotate((d) => (d as any).rotate)
      .font(fontFamily)
      .fontSize((d) => (d as any).size)
      .on('end', (words) => {
        // Draw the word cloud
        const colorScale = d3.scaleOrdinal(colors);
        
        const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
        g.setAttribute('transform', `translate(${width / 2},${height / 2})`);
        
        words.forEach((d, i) => {
          const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
          text.setAttribute('text-anchor', 'middle');
          text.setAttribute('transform', `translate(${d.x},${d.y}) rotate(${d.rotate})`);
          text.setAttribute('font-size', `${d.size}px`);
          text.setAttribute('font-family', fontFamily);
          text.setAttribute('fill', colorScale(i.toString()));
          text.textContent = d.text || '';
          g.appendChild(text);
        });
        
        svg.appendChild(g);
      });
    
    layout.start();
  }, [text, language, width, height, fontFamily, maxWords, colors, padding, minFontSize, maxFontSize, rotationAngles, rotationProbability]);

  return (
    <svg
      ref={containerRef}
      width={width}
      height={height}
      className={className}
      style={style}
    />
  );
};

export default WordCloud;
