import os
import re
import xml.etree.ElementTree as ET
from docx import Document

def generate_xml(docx_file, output_folder):
    document = Document(docx_file)
    verse_num = 1
    verse_type = 'V'
    song_count = 0
    lines_text = ''
    verse_order_set = set()
    verseOrder = None
    lyrics = None
    root = None
    lines = None
    for i, para in enumerate(document.paragraphs):
        
        if para.style.name == 'Heading 1':
            root = ET.Element("song")
            root.set("xmlns", "http://openlyrics.info/namespace/2009/song")
            root.set("version", "0.8")
            root.set("createdIn", "OpenLP 2.4.3")
            root.set("modifiedIn", "FreeWorship 3.2301.280.0")
            root.set("modifiedDate", "2023-04-27T18:47:00")

            properties = ET.SubElement(root, 'properties')
            
            titles = ET.SubElement(properties, 'titles')
            title = ET.SubElement(titles, 'title')
            title.text = para.text
            authors = ET.SubElement(properties, 'authors')
            author = ET.SubElement(authors, 'author')
            author.text="Author Unknown"
            verseOrder = ET.SubElement(properties, 'verseOrder')
            verseOrder.text = ''
            songbooks = ET.SubElement(properties, 'songbooks')
            songbook = ET.SubElement(songbooks, 'songbook')
            songbook.set("name","Superbook")
            songbook.set("entry","SuperBook")
            lyrics = ET.SubElement(root, 'lyrics')
            song_count += 1
            verse_order_set.clear()
            verse_num = 1
            bridge_num = 1
            chorus_num = 1
        else:
            if para.text.strip():
                first_word = para.text.split()[0]
                if (first_word[-1] == '.' or first_word[-1] == ')') and first_word[:-1].isdigit():
                    if lines_text and lines is not None:
                        lines.text = lines_text[:-5]
                        lines_text = ''
                    verse_num += 1
                    verse_type = 'V'
                    para.text = para.text[len(first_word):].strip()
                    verse_name = f'{verse_type}{verse_num}'
                elif 'Coro' in first_word:
                    if lines_text and lines is not None:
                        lines.text = lines_text[:-5]
                        lines_text = ''
                    verse_type = 'C'
                    para.text = para.text[len(first_word):].strip()
                    verse_name = f'{verse_type}{chorus_num}'
                    
                    chorus_num += 1
                elif first_word == 'Bridge:':
                    if lines_text and lines is not None:
                        lines.text = lines_text[:-5]
                        lines_text = ''
                    verse_type = 'B'
                    para.text = para.text[len(first_word):].strip()
                    
                    verse_name = f'{verse_type}{bridge_num}'
                    bridge_num += 1
                else:
                    verse_type = 'V'
                    verse_name = f'{verse_type}{verse_num}'
                if verse_name not in verse_order_set:
                    if verseOrder is not None:
                        if not verseOrder.text:
                            verseOrder.text += f'{verse_name}'
                        else:
                            verseOrder.text += f' {verse_name}'
                        verse_order_set.add(verse_name)
                if not lines_text and lyrics is not None:
                    verse = ET.SubElement(lyrics, 'verse', attrib={'name': verse_name, 'lang': ''})
                    lines= ET.SubElement(verse, 'lines')
                text_runs = []
                for run in para.runs:
                    if run.font.color.rgb is None or run.font.color.rgb == "000000":
                        text_runs.append(run.text)
                    else:
                        words = run.text.split()
                        bracketed_words = ['[' + word + ']' for word in words]
                        text_runs.append(' '.join(bracketed_words)+"\n")
                para_text = ''.join(text_runs).replace('\n','<br/>') +'<br/>'
                lines_text += para_text+"\n"
        
        if i == len(document.paragraphs) - 1 or document.paragraphs[i + 1].style.name == 'Heading 1':
            if root is not None:
                if lines_text and lyrics is not None and lines is not None:
                    lines.text = lines_text[:-5]
                    
                    lines_text = ''
                    
                tree = ET.ElementTree(root)
                filename = re.sub(r'[^\w\s-]', '', title.text).strip().lower()
               # filename = re.sub(r'[-\s]+', '-', filename)
                output_file = os.path.join(output_folder, f'{filename}.xml')
                tree.write(output_file, encoding='utf-8', xml_declaration=True)

generate_xml("C:/Users/Daniele/Downloads/test.docx","C:/Users/Daniele/Downloads/xml")
