/**
 * HighlightManager - Gestionnaire de mise en évidence des preuves
 * 
 * Responsabilités:
 * - Appliquer les couleurs selon le type de code (DP=bleu, DR=vert, DAS=jaune, CCAM=violet)
 * - Gérer la limite de 1000 highlights simultanés
 * - Afficher les tooltips au survol
 * - Gérer le scroll automatique vers les zones mises en évidence
 * 
 * Validates: Requirements 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 12.6, 12.7
 */
class HighlightManager {
  constructor() {
    this.highlightConfig = {
      'dp': { color: '#3b82f6', bgColor: 'rgba(59, 130, 246, 0.2)', label: 'DP' },
      'dr': { color: '#10b981', bgColor: 'rgba(16, 185, 129, 0.2)', label: 'DR' },
      'das': { color: '#f59e0b', bgColor: 'rgba(245, 158, 11, 0.2)', label: 'DAS' },
      'ccam': { color: '#8b5cf6', bgColor: 'rgba(139, 92, 246, 0.2)', label: 'CCAM' }
    };
    
    this.maxHighlights = 1000;
    this.currentHighlights = [];
    this.tooltip = null;
    
    this.createTooltip();
  }

  /**
   * Créer l'élément tooltip
   */
  createTooltip() {
    this.tooltip = document.createElement('div');
    this.tooltip.className = 'highlight-tooltip';
    this.tooltip.style.display = 'none';
    document.body.appendChild(this.tooltip);
  }

  /**
   * Appliquer les highlights sur un document
   * Validates: Requirements 4.3, 4.4, 4.5, 4.6, 4.7, 12.6
   */
  applyHighlights(container, evidence, codeType, originalContent = null) {
    // Nettoyer les highlights précédents
    this.clearHighlights(container);
    
    if (!evidence || evidence.length === 0) {
      return;
    }
    
    // Vérifier la limite de highlights
    if (evidence.length > this.maxHighlights) {
      this.showHighlightWarning(container, evidence.length);
      return;
    }
    
    const config = this.highlightConfig[codeType] || this.highlightConfig['dp'];
    
    // Utiliser le contenu original si fourni, sinon utiliser textContent
    // IMPORTANT: textContent normalise les espaces, ce qui décale les positions!
    const content = originalContent || container.textContent;
    
    // Trier les preuves par position pour éviter les chevauchements
    const sortedEvidence = [...evidence].sort((a, b) => a.span.start - b.span.start);
    
    // Créer les fragments de texte avec highlights
    let lastIndex = 0;
    const fragments = [];
    
    sortedEvidence.forEach((ev, index) => {
      // Texte avant le highlight
      if (ev.span.start > lastIndex) {
        fragments.push({
          type: 'text',
          content: content.substring(lastIndex, ev.span.start)
        });
      }
      
      // Highlight
      fragments.push({
        type: 'highlight',
        content: content.substring(ev.span.start, ev.span.end),
        evidence: ev,
        config: config,
        index: index
      });
      
      lastIndex = ev.span.end;
    });
    
    // Texte après le dernier highlight
    if (lastIndex < content.length) {
      fragments.push({
        type: 'text',
        content: content.substring(lastIndex)
      });
    }
    
    // Construire le HTML
    let html = '';
    fragments.forEach(fragment => {
      if (fragment.type === 'text') {
        html += this.escapeHTML(fragment.content);
      } else {
        html += this.createHighlightHTML(fragment);
      }
    });
    
    container.innerHTML = html;
    
    // Attacher les événements
    this.attachHighlightEvents(container);
    
    this.currentHighlights = sortedEvidence;
  }

  /**
   * Créer le HTML d'un highlight
   */
  createHighlightHTML(fragment) {
    return `<span class="evidence-highlight" 
                  style="background-color: ${fragment.config.bgColor}; 
                         border-bottom: 2px solid ${fragment.config.color}; 
                         cursor: pointer;
                         padding: 2px 4px;
                         border-radius: 3px;"
                  data-evidence-index="${fragment.index}"
                  data-code-type="${fragment.config.label}"
                  data-document-id="${fragment.evidence.document_id}">
              ${this.escapeHTML(fragment.content)}
            </span>`;
  }

  /**
   * Échapper le HTML pour prévenir les attaques XSS
   * Validates: Requirements 16.2
   */
  escapeHTML(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }

  /**
   * Attacher les événements aux highlights
   * Validates: Requirements 4.8, 4.9
   */
  attachHighlightEvents(container) {
    const highlights = container.querySelectorAll('.evidence-highlight');
    
    highlights.forEach(highlight => {
      // Tooltip au survol
      highlight.addEventListener('mouseenter', (e) => {
        const codeType = e.target.dataset.codeType;
        const index = e.target.dataset.evidenceIndex;
        const evidence = this.currentHighlights[index];
        
        this.showTooltip(e, codeType, evidence);
      });
      
      highlight.addEventListener('mouseleave', () => {
        this.hideTooltip();
      });
      
      highlight.addEventListener('mousemove', (e) => {
        this.updateTooltipPosition(e);
      });
      
      // Clic pour sélectionner le code
      highlight.addEventListener('click', (e) => {
        const index = e.target.dataset.evidenceIndex;
        const evidence = this.currentHighlights[index];
        this.onHighlightClick(evidence);
      });
    });
  }

  /**
   * Afficher le tooltip
   */
  showTooltip(event, codeType, evidence) {
    if (!this.tooltip) return;
    
    this.tooltip.innerHTML = `
      <div class="tooltip-header">${codeType}</div>
      <div class="tooltip-content">
        ${evidence.text ? this.escapeHTML(evidence.text.substring(0, 100)) + '...' : 'Preuve'}
      </div>
    `;
    
    this.tooltip.style.display = 'block';
    this.updateTooltipPosition(event);
  }

  /**
   * Mettre à jour la position du tooltip
   */
  updateTooltipPosition(event) {
    if (!this.tooltip) return;
    
    const x = event.clientX + 10;
    const y = event.clientY + 10;
    
    this.tooltip.style.left = x + 'px';
    this.tooltip.style.top = y + 'px';
  }

  /**
   * Masquer le tooltip
   */
  hideTooltip() {
    if (this.tooltip) {
      this.tooltip.style.display = 'none';
    }
  }

  /**
   * Gérer le clic sur un highlight
   */
  onHighlightClick(evidence) {
    // Émettre un événement pour que d'autres composants puissent réagir
    const event = new CustomEvent('highlightClicked', { 
      detail: { evidence } 
    });
    document.dispatchEvent(event);
  }

  /**
   * Scroller vers un highlight spécifique
   * Validates: Requirements 7.2, 7.4
   */
  scrollToHighlight(container, evidenceIndex) {
    const highlight = container.querySelector(`[data-evidence-index="${evidenceIndex}"]`);
    if (highlight) {
      highlight.scrollIntoView({ 
        behavior: 'smooth', 
        block: 'center' 
      });
      
      // Animation de flash pour attirer l'attention
      highlight.style.animation = 'highlight-flash 1s ease';
      setTimeout(() => {
        highlight.style.animation = '';
      }, 1000);
    }
  }

  /**
   * Nettoyer les highlights
   */
  clearHighlights(container) {
    if (!container) return;
    
    // Sauvegarder le contenu texte original
    const originalText = container.textContent;
    container.textContent = originalText;
    
    this.currentHighlights = [];
  }

  /**
   * Afficher un avertissement si trop de highlights
   * Validates: Requirements 12.7
   */
  showHighlightWarning(container, count) {
    container.innerHTML = `
      <div class="highlight-warning">
        <h3>⚠️ Trop de preuves à afficher</h3>
        <p>Ce document contient ${count} preuves, ce qui dépasse la limite de ${this.maxHighlights} highlights simultanés.</p>
        <p>Veuillez utiliser les filtres pour réduire le nombre de preuves affichées.</p>
      </div>
    `;
  }

  /**
   * Mettre en évidence toutes les preuves d'un code
   */
  highlightCodeEvidence(container, code) {
    if (!code || !code.evidence) {
      this.clearHighlights(container);
      return;
    }
    
    this.applyHighlights(container, code.evidence, code.type);
  }

  /**
   * Obtenir le nombre de highlights actifs
   */
  getHighlightCount() {
    return this.currentHighlights.length;
  }
}

// Export pour utilisation dans d'autres modules
if (typeof module !== 'undefined' && module.exports) {
  module.exports = HighlightManager;
}
