<?php

use RenanBr\BibTexParser\Listener;
use RenanBr\BibTexParser\Parser;
use RenanBr\BibTexParser\Processor;
use RenanBr\BibTexParser\Processor\NamesProcessor;
use RenanBr\BibTexParser\Processor\LatexToUnicodeProcessor;

require dirname(__FILE__).'/common.php';

function removeBoundingBraces($str) {
    // Trim whitespace first
    $str = trim($str);
    
    // Check if string starts with { and ends with }
    if (strlen($str) >= 2) {
        // Remove opening brace if it exists
        if ($str[0] === '{') {
            $str = substr($str, 1);
        }
        
        // After removing first brace, get new length
        $length = strlen($str);
        
        // Remove closing brace if it exists
        if ($length > 0 && $str[$length - 1] === '}') {
            $str = substr($str, 0, -1);
        }
    }
    
    return $str;
}


function expandJournalAbbreviation($abbrev) {
    // Define mapping of abbreviations (including LaTeX macros) to full journal names
    $journalMap = [
        // Standard abbreviations
        'AJ'        => 'The Astronomical Journal',
        'ApJ'       => 'The Astrophysical Journal',
        'ApJL'      => 'The Astrophysical Journal Letters',
        'ApJS'      => 'The Astrophysical Journal Supplement Series',
        'ARA&A'     => 'Annual Review of Astronomy and Astrophysics',
        'ARAA'      => 'Annual Review of Astronomy and Astrophysics',
        'ARAP'      => 'Annual Review of Astronomy and Astrophysics',
        'MNRAS'     => 'Monthly Notices of the Royal Astronomical Society',
        'PASP'      => 'Publications of the Astronomical Society of the Pacific',
        'PASJ'      => 'Publications of the Astronomical Society of Japan',
        'A&A'       => 'Astronomy & Astrophysics',
        'A&AS'      => 'Astronomy & Astrophysics Supplement Series',
        
        // LaTeX macros
        '\aj'       => 'The Astronomical Journal',
        '\apj'      => 'The Astrophysical Journal',
        '\apjl'     => 'The Astrophysical Journal Letters',
        '\apjlett'  => 'The Astrophysical Journal Letters',
        '\apjs'     => 'The Astrophysical Journal Supplement Series',
        '\apjsupp'  => 'The Astrophysical Journal Supplement Series',
        '\araa'     => 'Annual Review of Astronomy and Astrophysics',
        '\mnras'    => 'Monthly Notices of the Royal Astronomical Society',
        '\pasp'     => 'Publications of the Astronomical Society of the Pacific',
        '\pasj'     => 'Publications of the Astronomical Society of Japan',
        '\aap'      => 'Astronomy & Astrophysics',
        '\aaps'     => 'Astronomy & Astrophysics Supplement Series',
        '\aapr'     => 'Astronomy & Astrophysics Reviews',
        '\solphys'  => 'Solar Physics',
        '\pasa'     => 'Publications of the Astronomical Society of Australia',
        '\jcap'     => 'Journal of Cosmology and Astroparticle Physics',
        '\nat'      => 'Nature',
        '\science'  => 'Science',
        '\icarus'   => 'Icarus',
        '\prd'      => 'Physical Review D',
        '\prl'      => 'Physical Review Letters',
        '\grl'      => 'Geophysical Research Letters',
        '\jgr'      => 'Journal of Geophysical Research',
        '\baas'     => 'Bulletin of the American Astronomical Society',
        '\physrep'  => 'Physics Reports',
        '\apss'     => 'Astrophysics and Space Science'
    ];

    // Clean the input
    $abbrev = trim($abbrev);
    
    // Handle case sensitivity for standard abbreviations
    if (!str_starts_with($abbrev, '\\') && isset($journalMap[strtoupper($abbrev)])) {
        $abbrev = strtoupper($abbrev);
    }
    
    // Return the full name if found, otherwise return original abbreviation
    return $journalMap[$abbrev] ?? $abbrev;
}

// Function to process text that might contain multiple journal references
function expandJournalReferences($text) {
    // First handle LaTeX macros that might be followed by spaces or punctuation
    $pattern = '/\\\\[a-zA-Z]+/';
    $text = preg_replace_callback($pattern, function($matches) {
        return expandJournalAbbreviation($matches[0]);
    }, $text);
    
    // Then handle standard abbreviations
    $words = explode(' ', $text);
    $result = [];
    
    foreach ($words as $word) {
        if (!str_starts_with($word, 'The ')) {  // Avoid re-processing already expanded journals
            $result[] = expandJournalAbbreviation($word);
        } else {
            $result[] = $word;
        }
    }
    
    return implode(' ', $result);
}


function convertFirstNameToInitial($name) {
    // Trim any whitespace
    $name = trim($name);
    
    // Return empty string if name is empty
    if (empty($name)) {
        return '';
    }
    
    // Split the name into parts
    $parts = preg_split('/\s+/', $name);
    
    // Process each part
    $result = array_map(function($part) {
        // Skip if part is empty
        if (empty($part)) {
            return '';
        }
        
        // If it's already an initial (single character followed by optional period)
        if (preg_match('/^[A-Z]\.?$/', $part)) {
            // Ensure it has a period
            return rtrim($part, '.') . '.';
        }
        
        // If it's a hyphenated name, handle each part
        if (strpos($part, '-') !== false) {
            $hyphenParts = explode('-', $part);
            $initials = array_map(function($p) {
                if (!empty($p)) {
                  return ucfirst($p[0]) . '.';
                }
                return '';
            }, $hyphenParts);
            return implode('-', $initials);
        }
        
        // Regular name: take first character, capitalize it, add period
        return ucfirst($part[0]) . '.';
    }, $parts);
    
    // Join the parts back together
    return implode(' ', array_filter($result));
}

$m = setup_mustache();



// Create and configure a Listener
$listener = new Listener();
$listener->addProcessor(new Processor\TagNameCaseProcessor(CASE_LOWER));
$listener->addProcessor(new NamesProcessor());
$listener->addProcessor(static function (array $entry) {
    $entry['title'] = removeBoundingBraces($entry['title']);
    foreach ($entry['author'] as $i=>$v) {
      $entry['author'][$i]['first'] = convertFirstNameToInitial($v['first']);
      $entry['author'][$i]['last'] = removeBoundingBraces($v['last']);
    }
    if (isset($entry['journal'])) {
      $entry['journal'] = expandJournalReferences($entry['journal']);
    }
    return $entry;
});
$listener->addProcessor(new LatexToUnicodeProcessor());

// Create a Parser and attach the listener
$parser = new Parser();
$parser->addListener($listener);

// Parse the content, then read processed data from the Listener
try {
  $parser->parseFile('assets/bib/export-bibtex.bib');
  $entries = $listener->export();
  
  $tpl = $m->loadTemplate("publi_bib_html");


echo $tpl->render(
  array(
    'ROOT_URL' => $iap_root,
    'title'=>'Guilhem Lavaux\'s publications',
    'publi'=>$entries,
    'configure_script'=>[
      'MathJax = {
  tex: {
    inlineMath: [[\'$\', \'$\'], [\'\\\\(\', \'\\\\)\']]
  }
};
      '
    ],
    'external_scripts'=>[
      'src="https://polyfill.io/v3/polyfill.min.js?features=es6"',
      'id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"'
    ],
    'bar' => 'baz'));

} catch (Exception $e) {
  echo $e->getMessage() . "<br/>";
}