/**
 * Bibliography Generator
 * 
 * Converts research sources (URLs) into BibTeX citations.
 * Shared utility used by both Research Agent and Dashboard.
 * 
 * Features:
 * - Detects source types (arXiv, PubMed, DOI, Wikipedia, etc.)
 * - Generates appropriate BibTeX entry types
 * - Creates unique citation keys
 * - Handles metadata extraction from URLs
 */

class BibliographyGenerator {
  /**
   * Generate BibTeX file from array of source URLs
   * 
   * @param {Array<string|Object>} sources - Array of URLs or source objects with {url, title}
   * @param {Object} metadata - Optional metadata {runName, agentId, description}
   * @returns {string} Complete BibTeX file content
   */
  static generateBibTeX(sources, metadata = {}) {
    const { runName, agentId, description } = metadata;
    
    let bibtex = `% Generated by COSMO Research Agent\n`;
    if (runName) bibtex += `% Run: ${runName}\n`;
    if (agentId) bibtex += `% Agent: ${agentId}\n`;
    if (description) bibtex += `% Mission: ${description}\n`;
    bibtex += `% Generated: ${new Date().toISOString()}\n`;
    bibtex += `% Total Sources: ${sources.length}\n\n`;
    
    sources.forEach((source, i) => {
      // Handle both string URLs and source objects with metadata
      const url = typeof source === 'string' ? source : source.url;
      const title = typeof source === 'object' ? source.title : null;
      
      if (!url) return; // Skip if no URL
      
      const citationKey = this.generateCitationKey(url, i);
      const entry = this.urlToBibTeX(url, citationKey, title);
      bibtex += entry + '\n\n';
    });
    
    return bibtex;
  }

  /**
   * Generate unique citation key from URL
   * 
   * @param {string} url - Source URL
   * @param {number} index - Fallback index for uniqueness
   * @returns {string} Citation key
   */
  static generateCitationKey(url, index) {
    try {
      const urlObj = new URL(url);
      const domain = urlObj.hostname.replace(/^www\./, '').replace(/\./g, '_');
      
      // Extract identifier from path
      let identifier = '';
      
      if (url.includes('arxiv.org')) {
        const match = url.match(/(\d+\.\d+)/);
        identifier = match ? `arxiv_${match[1].replace('.', '_')}` : `arxiv_${index}`;
      } else if (url.includes('doi.org')) {
        const match = url.match(/10\.\d+\/([^?]+)/);
        identifier = match ? match[1].replace(/[\/\.]/g, '_') : `doi_${index}`;
      } else if (url.includes('pubmed')) {
        const match = url.match(/(\d+)/);
        identifier = match ? `pubmed_${match[1]}` : `pubmed_${index}`;
      } else if (url.includes('github.com')) {
        const match = url.match(/github\.com\/([^/]+)\/([^/]+)/);
        identifier = match ? `github_${match[1]}_${match[2]}` : `github_${index}`;
      } else {
        identifier = `${domain}_${index}`;
      }
      
      return identifier;
    } catch (error) {
      return `source_${index}`;
    }
  }

  /**
   * Convert URL to BibTeX entry
   * 
   * @param {string} url - Source URL
   * @param {string} citationKey - Unique citation key
   * @param {string|null} title - Optional title from citation metadata
   * @returns {string} BibTeX entry
   */
  static urlToBibTeX(url, citationKey, title = null) {
    try {
      const urlObj = new URL(url);
      const hostname = urlObj.hostname;
      const accessDate = new Date().toISOString().split('T')[0];
      
      // Detect source type and generate appropriate entry
      if (url.includes('arxiv.org')) {
        const match = url.match(/abs\/(\d+\.\d+)/);
        const arxivId = match ? match[1] : 'unknown';
        const entryTitle = title || `arXiv Preprint ${arxivId}`;
        
        return `@misc{${citationKey},
  title = {${entryTitle}},
  author = {Various},
  year = {${new Date().getFullYear()}},
  eprint = {${arxivId}},
  archivePrefix = {arXiv},
  url = {${url}}
}`;
      } else if (url.includes('pubmed') || url.includes('pmc.ncbi')) {
        const match = url.match(/(\d+)/);
        const pmid = match ? match[1] : 'unknown';
        const entryTitle = title || `PubMed Article ${pmid}`;
        
        return `@article{${citationKey},
  title = {${entryTitle}},
  author = {Various},
  journal = {PubMed},
  year = {${new Date().getFullYear()}},
  note = {PMID: ${pmid}},
  url = {${url}}
}`;
      } else if (url.includes('doi.org')) {
        const match = url.match(/10\.\d+\/([^?]+)/);
        const doi = match ? match[0] : 'unknown';
        const entryTitle = title || `DOI Reference`;
        
        return `@article{${citationKey},
  title = {${entryTitle}},
  author = {Various},
  year = {${new Date().getFullYear()}},
  doi = {${doi}},
  url = {${url}}
}`;
      } else if (url.includes('wikipedia.org')) {
        const match = url.match(/\/wiki\/([^?#]+)/);
        const article = match ? decodeURIComponent(match[1]).replace(/_/g, ' ') : 'Article';
        const entryTitle = title || article;
        
        return `@misc{${citationKey},
  title = {${entryTitle}},
  author = {Wikipedia},
  year = {${new Date().getFullYear()}},
  howpublished = {\\url{${url}}},
  note = {Online; accessed ${accessDate}}
}`;
      } else if (url.includes('academic.oup.com') || url.includes('cambridge.org')) {
        const publisher = hostname.includes('oup') ? 'Oxford University Press' : 'Cambridge University Press';
        const entryTitle = title || 'Academic Publication';
        
        return `@book{${citationKey},
  title = {${entryTitle}},
  author = {Various},
  publisher = {${publisher}},
  year = {${new Date().getFullYear()}},
  url = {${url}}
}`;
      } else if (url.includes('github.com')) {
        const match = url.match(/github\.com\/([^/]+)\/([^/]+)/);
        const repo = match ? `${match[1]}/${match[2]}` : 'Repository';
        const entryTitle = title || `GitHub: ${repo}`;
        
        return `@misc{${citationKey},
  title = {${entryTitle}},
  author = {${match ? match[1] : 'Various'}},
  year = {${new Date().getFullYear()}},
  howpublished = {GitHub Repository},
  url = {${url}},
  note = {Accessed ${accessDate}}
}`;
      } else {
        // Generic web source
        const entryTitle = title || 'Web Resource';
        
        return `@misc{${citationKey},
  title = {${entryTitle}},
  author = {${hostname}},
  year = {${new Date().getFullYear()}},
  howpublished = {\\url{${url}}},
  note = {Accessed ${accessDate}}
}`;
      }
    } catch (error) {
      const entryTitle = title || 'Source Reference';
      
      return `@misc{${citationKey},
  title = {${entryTitle}},
  url = {${url}},
  note = {Accessed ${new Date().toISOString().split('T')[0]}}
}`;
    }
  }
}

module.exports = { BibliographyGenerator };

