*! reftex v9.6 - Enhanced bibliography processor with LaTeX escaping and mixed language support
*! Author 1: Wu Lianghai
*! Author 2: Wu Hanyan
*! Author 3: Chen Liwen
*!------------------------------------------------------------------------------

cap program drop reftex
cap program drop convert_bibliography
cap program drop process_entry
cap program drop process_english_entry
cap program drop escape_latex

* LaTeX escaping helper
program define escape_latex, rclass
    version 16
    args str
    if `"`str'"' == "" {
        return local escaped ""
        exit
    }
    local str = subinstr(`"`str'"', "\", "\\", .)
    local str = subinstr(`"`str'"', "&", "\&", .)
    local str = subinstr(`"`str'"', "%", "\%", .)
    local str = subinstr(`"`str'"', "$", "\$", .)
    local str = subinstr(`"`str'"', "#", "\#", .)
    local str = subinstr(`"`str'"', "_", "\_", .)
    local str = subinstr(`"`str'"', "{", "\{", .)
    local str = subinstr(`"`str'"', "}", "\}", .)
    return local escaped `"`str'"'
end

program define reftex
    version 16
    syntax using/, outfile(string) [debug replace lang(string)]

    * Default language is Chinese
    if "`lang'" == "" local lang "chn"

    * Validate language option
    if !inlist("`lang'", "chn", "eng", "mix") {
        di as error "Invalid lang() option. Valid values: chn, eng or mix"
        exit 198
    }

    convert_bibliography "`using'" "`outfile'" "`debug'" "`replace'" "`lang'"
    di as result "Bibliography converted successfully!"
    di as text "Output saved to: " as result "`outfile'"
    di as text "Language: " as result upper("`lang'")
end

program define convert_bibliography
    args infile outfile debug replace_option lang

    * File handling
    capture confirm file "`outfile'"
    if _rc == 0 & "`replace_option'" == "" {
        di as error "File `outfile' already exists. Use replace option to overwrite."
        exit 602
    }
    if "`replace_option'" != "" capture erase "`outfile'"

    tempname fh_in fh_out
    file open `fh_in' using "`infile'", read text
    file open `fh_out' using "`outfile'", write text

    * Write only thebibliography environment for natbib compatibility
    file write `fh_out' "% Bibliography generated by reftex" _n
    file write `fh_out' "% Date: `c(current_date)'" _n
    file write `fh_out' "% Language: `lang'" _n _n
    file write `fh_out' "\begin{thebibliography}{99}" _n

    local entry ""
    local entry_count 0
    local debug_flag = ("`debug'" != "")
    local line_count 0

    * Read first line
    file read `fh_in' line

    * Process each line
    while r(eof)==0 {
        local line_count = `line_count' + 1

        * Remove BOM and trim
        local line = subinstr(`"`macval(line)'"', char(65279), "", .)
        local line = strtrim(`"`macval(line)'"')

        if `debug_flag' di "Line `line_count': `line'"

        * Detect entry start: [number] at beginning of line
        if regexm(`"`line'"', "^\s*\[[0-9]+\]") {
            * Process previous entry if exists
            if `"`entry'"' != "" {
                local entry_count = `entry_count' + 1
                if `debug_flag' di "Processing stored entry (#`entry_count')"

                * Mixed language detection logic
                if "`lang'" == "mix" {
                    if (ustrregexm(`"`entry'"', "[\u4e00-\u9fff]")) {
                        if `debug_flag' di "Detected CHINESE entry"
                        process_entry `"`entry'"' "`debug'" "`fh_out'" `entry_count'
                    }
                    else {
                        if `debug_flag' di "Detected ENGLISH entry"
                        process_english_entry `"`entry'"' "`debug'" "`fh_out'" `entry_count'
                    }
                }
                else if "`lang'" == "chn" {
                    process_entry `"`entry'"' "`debug'" "`fh_out'" `entry_count'
                }
                else if "`lang'" == "eng" {
                    process_english_entry `"`entry'"' "`debug'" "`fh_out'" `entry_count'
                }
            }
            local entry `"`line'"'
            if `debug_flag' di "New entry started: `line'"
        }
        * Continue existing entry
        else if `"`entry'"' != "" {
            * Add space only if not first token
            if ustrlen(`"`entry'"') > 0 {
                local entry `"`entry' `line'"'
            }
            else {
                local entry `"`line'"'
            }
            if `debug_flag' di "Appending to entry: `line'"
        }
        else if `debug_flag' {
            di "Skipping line (no active entry): `line'"
        }

        file read `fh_in' line
    }

    * Process last entry
    if `"`entry'"' != "" {
        local entry_count = `entry_count' + 1
        if `debug_flag' di "Processing final entry (#`entry_count')"

        * Mixed language detection logic
        if "`lang'" == "mix" {
            if (ustrregexm(`"`entry'"', "[\u4e00-\u9fff]")) {
                if `debug_flag' di "Detected CHINESE entry"
                process_entry `"`entry'"' "`debug'" "`fh_out'" `entry_count'
            }
            else {
                if `debug_flag' di "Detected ENGLISH entry"
                process_english_entry `"`entry'"' "`debug'" "`fh_out'" `entry_count'
            }
        }
        else if "`lang'" == "chn" {
            process_entry `"`entry'"' "`debug'" "`fh_out'" `entry_count'
        }
        else if "`lang'" == "eng" {
            process_english_entry `"`entry'"' "`debug'" "`fh_out'" `entry_count'
        }
    }

    file write `fh_out' _n "\end{thebibliography}"
    file close `fh_in'
    file close `fh_out'

    if `entry_count' == 0 {
        di as error "Warning: No valid entries processed"
        di as text "Check input file format. Use debug option for details."
    }
    else {
        di "Successfully processed `entry_count' entries"
    }
end

* Process Chinese bibliography entries
program define process_entry
    args entry debug fh_out entry_count

    if "`debug'" != "" di "Processing CHINESE entry: `entry'"

    * Clean entry - remove numbering prefix
    local entry = regexr(`"`entry'"', "^\s*\[[0-9]+\]\s*", "")
    local entry = strtrim(`"`entry'"')
    if "`debug'" != "" di "Cleaned entry: `entry'"

    * Extract year (handle Chinese formats)
    local year ""
    if regexm(`"`entry'"', "([0-9]{4})") {
        local year = regexs(1)
    }
    if "`year'" == "" {
        if "`debug'" != "" di "Year not found"
        local year "0000"
    }

    * Split author and rest
    local author = regexr(`"`entry'"', "`year'.*", "")
    local rest = regexr(`"`entry'"', "^.*?`year'", "")
    local author = strtrim(`"`author'"')
    local rest = strtrim(`"`rest'"')

    * Clean leading punctuation from rest
    local rest = ustrregexra(`"`rest'"', "^[，、。：:\s]+", "")

    * Escape LaTeX special characters
    escape_latex `"`author'"'
    local author_escaped = `"`r(escaped)'"'
    escape_latex `"`rest'"'
    local rest_escaped = `"`r(escaped)'"'

    * Generate citation key (first author + year)
    local first_author = ustrword(`"`author'"', 1)
    local citation_key = "`first_author'`year'"

    * Output entire entry with title
    file write `fh_out' _n "\bibitem[`author_escaped' (`year')]{`citation_key'}"
    file write `fh_out' _n "`author_escaped' (`year'). `rest_escaped'"

    if "`debug'" != "" {
        di "Generated CHINESE entry`entry_count' with key: `citation_key'"
    }
end

* Process English bibliography entries (with double period fix)
program define process_english_entry
    args entry debug fh_out entry_count

    if "`debug'" != "" di "Processing ENGLISH entry: `entry'"

    * Clean entry - remove numbering prefix
    local entry = regexr(`"`entry'"', "^\s*\[[0-9]+\]\s*", "")
    local entry = strtrim(`"`entry'"')
    if "`debug'" != "" di "Cleaned entry: `entry'"

    * Extract year
    local year ""
    if regexm(`"`entry'"', "([0-9]{4})") {
        local year = regexs(1)
    }
    if "`year'" == "" {
        if "`debug'" != "" di "Year not found"
        local year "0000"
    }

    * Split author and rest
    local author_part = regexr(`"`entry'"', "`year'.*", "")
    local rest = regexr(`"`entry'"', "^.*?`year'", "")
    local author_part = strtrim(`"`author_part'"')
    local rest = strtrim(`"`rest'"')

    * Clean leading punctuation from rest
    local rest = ustrregexra(`"`rest'"', "^[,\s]+", "")

    * Extract authors
    local authors = ""
    if regexm(`"`author_part'"', "^(.+),\s+([0-9]{4})") {
        local authors = regexs(1)
    }
    else {
        local authors = `"`author_part'"'
    }

    * Format authors: remove trailing comma if exists
    local authors = ustrregexra(`"`authors'"', ",\s*$", "")

    * Generate citation key (first author + year)
    local first_author = ustrword(`"`authors'"', 1)
    local citation_key = "`first_author'`year'"

    * Split rest into components (title, journal, volume, pages)
    local components = ustrregexra(`"`rest'"', "\s{2,}", " ")  // Remove extra spaces
    local comma_count = strlen(ustrregexra(`"`components'"', "[^,]", ""))

    if `comma_count' >= 3 {
        * Standard format: Title, Journal, Volume, Pages
        if regexm(`"`components'"', "^(.+?),") {
            local title = regexs(1)
        }
        local after_title = regexr(`"`components'"', "^.+?,\s*", "")

        if regexm(`"`after_title'"', "^(.+?),") {
            local journal = regexs(1)
        }
        local after_journal = regexr(`"`after_title'"', "^.+?,\s*", "")

        local volume_pages = `"`after_journal'"'
    }
    else if `comma_count' == 2 {
        * Conference format: Title, Conference, Pages
        if regexm(`"`components'"', "^(.+?),") {
            local title = regexs(1)
        }
        local after_title = regexr(`"`components'"', "^.+?,\s*", "")

        if regexm(`"`after_title'"', "^(.+?),") {
            local journal = regexs(1)
        }
        local volume_pages = regexr(`"`after_title'"', "^.+?,\s*", "")
    }
    else {
        * Fallback: Use entire rest as title
        local title = `"`components'"'
        local journal = ""
        local volume_pages = ""
    }

    * Clean title and journal - remove trailing punctuation
    local title = ustrregexra(`"`title'"', "[,.\s]+$", "")
    local journal = ustrregexra(`"`journal'"', "[,.\s]+$", "")

    * Extract volume and pages
    local volume = ""
    local issue = ""
    local pages = ""

    if regexm(`"`volume_pages'"', "([0-9]+)\(([0-9]+)\)") {
        local volume = regexs(1)
        local issue = regexs(2)
        local pages = regexr(`"`volume_pages'"', "^.+?\),\s*", "")
    }
    else if regexm(`"`volume_pages'"', "([0-9]+):\s*([0-9\-]+)") {
        local volume = regexs(1)
        local pages = regexs(2)
    }
    else if regexm(`"`volume_pages'"', "([0-9]+),\s*([0-9\-]+)") {
        local volume = regexs(1)
        local pages = regexs(2)
    }
    else {
        local pages = `"`volume_pages'"'
    }

    * Clean extracted components - remove trailing punctuation
    local volume = ustrregexra(`"`volume'"', "[,.\s]+$", "")
    local issue = ustrregexra(`"`issue'"', "[,.\s]+$", "")
    local pages = ustrregexra(`"`pages'"', "[,.\s]+$", "")

    * Escape LaTeX special characters
    escape_latex `"`authors'"'
    local authors_escaped = `"`r(escaped)'"'
    escape_latex `"`title'"'
    local title_escaped = `"`r(escaped)'"'
    escape_latex `"`journal'"'
    local journal_escaped = `"`r(escaped)'"'
    escape_latex `"`volume'"'
    local volume_escaped = `"`r(escaped)'"'
    escape_latex `"`issue'"'
    local issue_escaped = `"`r(escaped)'"'
    escape_latex `"`pages'"'
    local pages_escaped = `"`r(escaped)'"'

    tempname temp_fh
    tempfile temp_file
    file open `temp_fh' using "`temp_file'", write text

    file write `temp_fh' "`authors_escaped' (`year') "
    file write `temp_fh' `"`title_escaped'"'

    if `"`journal_escaped'"' != "" {
        file write `temp_fh' ", "
        file write `temp_fh' "\textit{`journal_escaped'}"
    }

    if "`volume_escaped'" != "" {
        file write `temp_fh' ", "
        file write `temp_fh' "\textbf{`volume_escaped'}"

        if "`issue_escaped'" != "" {
            file write `temp_fh' "(`issue_escaped')"
        }
    }

    if "`pages_escaped'" != "" {
        if "`volume_escaped'" != "" | "`journal_escaped'" != "" {
            file write `temp_fh' ", "
        }
        file write `temp_fh' "`pages_escaped'"
    }

    file close `temp_fh'

    file open `temp_fh' using "`temp_file'", read text
    file read `temp_fh' entry_content
    file close `temp_fh'

    local entry_content = strtrim(`"`entry_content'"')

    local last_char = substr(`"`entry_content'"', -1, 1)
    if !inlist(`"`last_char'"', ".", "．", "?", "!", "？", "！") {
        local entry_content `"`entry_content'."'
    }

    file write `fh_out' _n "\bibitem[`authors_escaped' (`year')]{`citation_key'}" _n
    file write `fh_out' `"`entry_content'"'

    if "`debug'" != "" {
        di "Generated ENGLISH entry`entry_count' with key: `citation_key'"
        di "Authors: `authors_escaped'"
        di "Year: `year'"
        di "Title: `title_escaped'"
        di "Journal: `journal_escaped'"
        di "Volume: `volume_escaped'"
        di "Issue: `issue_escaped'"
        di "Pages: `pages_escaped'"
        di "Final content: `entry_content'"
    }
end