/**
 * DocumentsPanel - Panneau d'affichage des documents sources
 * 
 * Responsabilités:
 * - Gérer les onglets de documents
 * - Afficher le contenu des documents
 * - Intégrer HighlightManager pour mettre en évidence les preuves
 * - Gérer les clics sur les zones mises en évidence
 * - Synchroniser avec le panneau codes
 * 
 * Validates: Requirements 4.1, 4.2, 4.3, 4.9
 */
class DocumentsPanel {
  constructor(stateManager, highlightManager) {
    this.stateManager = stateManager;
    this.highlightManager = highlightManager;
    this.tabsContainer = document.getElementById('document-tabs');
    this.viewerContainer = document.getElementById('document-viewer');
    this.searchContainer = document.getElementById('documents-search');
    
    this.documents = [];
    this.currentSearchResults = [];
    this.currentSearchIndex = 0;
    
    // S'abonner aux changements d'état
    this.stateManager.on('stayChanged', (stay) => this.loadDocuments(stay));
    this.stateManager.on('codeSelected', (code) => this.highlightCodeEvidence(code));
    this.stateManager.on('documentTabChanged', (tabId) => this.switchToDocument(tabId));
    this.stateManager.on('searchTermChanged', (term) => this.performSearch(term));
    
    // Écouter les clics sur les highlights
    document.addEventListener('highlightClicked', (e) => {
      this.onHighlightClicked(e.detail.evidence);
    });
    
    this.renderSearchBar();
  }

  /**
   * Charger les documents d'un séjour
   */
  async loadDocuments(stay) {
    if (!stay) {
      this.documents = [];
      this.renderTabs();
      this.viewerContainer.innerHTML = '<p class="text-center" style="color: #718096; padding: 40px;">Aucun document disponible</p>';
      return;
    }
    
    // Utiliser les documents chargés depuis l'API
    if (stay.documents && stay.documents.length > 0) {
      this.documents = stay.documents;
    } else {
      this.documents = [];
    }
    
    this.renderTabs();
    
    if (this.documents.length > 0) {
      this.stateManager.setActiveDocumentTab(this.documents[0].document_id);
    } else {
      this.viewerContainer.innerHTML = '<p class="text-center" style="color: #718096; padding: 40px;">Aucun document disponible</p>';
    }
  }

  /**
   * Rendre les onglets de documents
   * Validates: Requirements 4.1
   */
  renderTabs() {
    if (this.documents.length === 0) {
      this.tabsContainer.innerHTML = '<p style="color: #718096; padding: 12px;">Aucun document</p>';
      return;
    }
    
    const activeTab = this.stateManager.getActiveDocumentTab() || this.documents[0].document_id;
    
    let html = '<div class="document-tabs-list">';
    this.documents.forEach(doc => {
      const isActive = doc.document_id === activeTab;
      html += `
        <button class="document-tab ${isActive ? 'active' : ''}" 
                data-document-id="${doc.document_id}"
                onclick="window.documentsPanel.selectTab('${doc.document_id}')">
          📄 ${doc.document_type}
        </button>
      `;
    });
    html += '</div>';
    
    this.tabsContainer.innerHTML = html;
  }

  /**
   * Sélectionner un onglet
   */
  selectTab(documentId) {
    this.stateManager.setActiveDocumentTab(documentId);
  }

  /**
   * Basculer vers un document
   * Validates: Requirements 4.2
   */
  switchToDocument(documentId) {
    const document = this.documents.find(d => d.document_id === documentId);
    if (!document) return;
    
    this.stateManager.setActiveDocument(document);
    this.renderDocument(document);
    this.renderTabs(); // Mettre à jour l'onglet actif
  }

  /**
   * Rendre le contenu d'un document
   */
  renderDocument(document) {
    if (!document) {
      this.viewerContainer.innerHTML = '<p class="text-center" style="color: #718096; padding: 40px;">Sélectionnez un document</p>';
      return;
    }
    
    this.viewerContainer.innerHTML = `
      <div class="document-content">
        <div class="document-header">
          <h3>${document.document_type}</h3>
          <div class="document-meta">
            <span>📅 ${new Date(document.creation_date).toLocaleDateString()}</span>
            <span>👤 ${document.author}</span>
          </div>
        </div>
        <div class="document-text" id="document-text-content">
          ${this.escapeHTML(document.content)}
        </div>
      </div>
    `;
    
    // Appliquer les highlights si un code est sélectionné
    const selectedCode = this.stateManager.getSelectedCode();
    if (selectedCode) {
      this.highlightCodeEvidence(selectedCode);
    }
  }

  /**
   * Mettre en évidence les preuves d'un code
   * Validates: Requirements 4.3, 7.1, 7.2
   */
  highlightCodeEvidence(code) {
    if (!code || !code.evidence) {
      return;
    }
    
    const activeDocument = this.stateManager.getActiveDocument();
    if (!activeDocument) return;
    
    // Filtrer les preuves pour le document actif
    const documentEvidence = code.evidence.filter(ev => 
      ev.document_id === activeDocument.document_id
    );
    
    const contentContainer = document.getElementById('document-text-content');
    if (contentContainer && documentEvidence.length > 0) {
      // IMPORTANT: Passer le contenu original du document, pas le textContent du DOM
      // car textContent normalise les espaces et décale les positions
      this.highlightManager.applyHighlights(
        contentContainer, 
        documentEvidence, 
        code.type,
        activeDocument.content  // Contenu original du document
      );
      
      // Scroller vers la première preuve
      setTimeout(() => {
        this.highlightManager.scrollToHighlight(contentContainer, 0);
      }, 100);
    }
  }

  /**
   * Gérer le clic sur un highlight
   * Validates: Requirements 4.9, 7.5, 7.6
   */
  onHighlightClicked(evidence) {
    // Trouver le code correspondant à cette preuve
    const stay = this.stateManager.getCurrentStay();
    if (!stay) return;
    
    const allCodes = [
      { code: stay.codes.dp, type: 'dp' },
      { code: stay.codes.dr, type: 'dr' },
      ...(stay.codes.das || []).map(c => ({ code: c, type: 'das' })),
      ...(stay.codes.ccam || []).map(c => ({ code: c, type: 'ccam' }))
    ].filter(item => item.code);
    
    // Trouver le code qui contient cette preuve
    for (const item of allCodes) {
      if (item.code.evidence) {
        const hasEvidence = item.code.evidence.some(ev => 
          ev.document_id === evidence.document_id &&
          ev.span.start === evidence.span.start &&
          ev.span.end === evidence.span.end
        );
        
        if (hasEvidence) {
          // Sélectionner ce code
          this.stateManager.setSelectedCode({ ...item.code, type: item.type });
          break;
        }
      }
    }
  }

  /**
   * Rendre la barre de recherche
   * Validates: Requirements 8.4
   */
  renderSearchBar() {
    this.searchContainer.innerHTML = `
      <div class="search-bar">
        <input type="text" 
               id="document-search-input" 
               placeholder="Rechercher dans le document..." 
               onkeyup="window.documentsPanel.onSearchInput(event)">
        <div class="search-controls">
          <button class="btn-icon" onclick="window.documentsPanel.previousSearchResult()" title="Résultat précédent">
            ⬆️
          </button>
          <span id="search-results-count">0/0</span>
          <button class="btn-icon" onclick="window.documentsPanel.nextSearchResult()" title="Résultat suivant">
            ⬇️
          </button>
        </div>
      </div>
    `;
  }

  /**
   * Gérer la saisie dans la recherche
   */
  onSearchInput(event) {
    const term = event.target.value;
    this.stateManager.setSearchTerm(term);
    
    // Naviguer au résultat suivant avec Entrée
    if (event.key === 'Enter') {
      this.nextSearchResult();
    }
  }

  /**
   * Effectuer une recherche dans le document
   * Validates: Requirements 8.5, 8.6, 8.7
   */
  performSearch(term) {
    const contentContainer = document.getElementById('document-text-content');
    if (!contentContainer || !term) {
      this.currentSearchResults = [];
      this.currentSearchIndex = 0;
      this.updateSearchCount();
      return;
    }
    
    const content = contentContainer.textContent;
    const regex = new RegExp(this.escapeRegex(term), 'gi');
    const matches = [...content.matchAll(regex)];
    
    this.currentSearchResults = matches.map(match => ({
      index: match.index,
      length: match[0].length
    }));
    
    this.currentSearchIndex = 0;
    this.updateSearchCount();
    
    if (this.currentSearchResults.length > 0) {
      this.highlightSearchResults(contentContainer, term);
      this.scrollToSearchResult(0);
    }
  }

  /**
   * Mettre en évidence les résultats de recherche
   */
  highlightSearchResults(container, term) {
    const content = container.textContent;
    const regex = new RegExp(`(${this.escapeRegex(term)})`, 'gi');
    const highlighted = content.replace(regex, '<mark class="search-highlight">$1</mark>');
    container.innerHTML = highlighted;
  }

  /**
   * Naviguer vers le résultat suivant
   */
  nextSearchResult() {
    if (this.currentSearchResults.length === 0) return;
    
    this.currentSearchIndex = (this.currentSearchIndex + 1) % this.currentSearchResults.length;
    this.scrollToSearchResult(this.currentSearchIndex);
    this.updateSearchCount();
  }

  /**
   * Naviguer vers le résultat précédent
   */
  previousSearchResult() {
    if (this.currentSearchResults.length === 0) return;
    
    this.currentSearchIndex = (this.currentSearchIndex - 1 + this.currentSearchResults.length) % this.currentSearchResults.length;
    this.scrollToSearchResult(this.currentSearchIndex);
    this.updateSearchCount();
  }

  /**
   * Scroller vers un résultat de recherche
   */
  scrollToSearchResult(index) {
    const highlights = document.querySelectorAll('.search-highlight');
    if (highlights[index]) {
      highlights[index].scrollIntoView({ behavior: 'smooth', block: 'center' });
      
      // Retirer la classe active des autres
      highlights.forEach(h => h.classList.remove('active'));
      highlights[index].classList.add('active');
    }
  }

  /**
   * Mettre à jour le compteur de résultats
   */
  updateSearchCount() {
    const countElement = document.getElementById('search-results-count');
    if (countElement) {
      const current = this.currentSearchResults.length > 0 ? this.currentSearchIndex + 1 : 0;
      countElement.textContent = `${current}/${this.currentSearchResults.length}`;
    }
  }

  /**
   * Échapper les caractères spéciaux pour regex
   */
  escapeRegex(string) {
    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  }

  /**
   * Échapper le HTML
   */
  escapeHTML(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }
}

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