import json
import re
import sys
from xml.sax.saxutils import escape

def parse_text(text, headword_original=""):
    lines = text.strip().split('\n')
    if not lines: return {}
    
    # Parse head line
    # Format typically: >[optional *][headword] [category]
    head_match = re.match(r'^>?(\*?\s*.+?)\s*(\[.*?\])?$', lines[0])
    kana = ""
    category = ""
    
    if head_match:
        kana = head_match.group(1).strip()
        category = head_match.group(2) if head_match.group(2) else ""
        if not category:
            print(f"WARNING: Entry '{headword_original}' missing category [] in: '{lines[0]}'")
    else:
        print(f"WARNING: Entry '{headword_original}' headword line format mismatch: '{lines[0]}'")
        kana = lines[0].lstrip(">").strip()
        
    senses = []
    subentries = []
    
    current_sense = None
    current_subentry = None
    
    def add_sense():
        if current_sense and (current_sense['meaning'] or current_sense['examples']):
            senses.append(current_sense)
            
    def add_subentry():
        if current_subentry:
            subentries.append(current_subentry)
    
    for i, line in enumerate(lines[1:]):
        line = line.strip()
        if not line: continue
        
        # Sub-entry starts with ◯
        if line.startswith('◯'):
            add_sense()
            current_sense = None
            add_subentry()
            
            parts = line.split('／', 1)
            sub_head = parts[0].strip()
            sub_mean = parts[1].strip() if len(parts) > 1 else ""
            if not sub_mean and len(parts) == 1 and ('／' not in line) and ('◇' not in line):
                 # Not a strict warning typically, some subentries might only have a headword, but we note it.
                 pass
            
            current_subentry = {
                'headword': sub_head,
                'meaning': sub_mean,
                'examples': []
            }
        # Example starts with ◇
        elif line.startswith('◇'):
            parts = line.split('／', 1)
            ja = parts[0].strip() # keeps ◇
            zh = parts[1].strip() if len(parts) > 1 else ""
            
            if len(parts) == 1:
                print(f"WARNING: Entry '{headword_original}' example missing '／' separator: '{line}'")
                
            eg = {'ja': ja, 'zh': zh}
            
            if current_subentry is not None:
                current_subentry['examples'].append(eg)
            else:
                if current_sense is None:
                    current_sense = {'index': '', 'meaning': '', 'examples': []}
                current_sense['examples'].append(eg)
        else:
            # Meaning could be numbered (1), (2), etc.
            m = re.match(r'^(\(\d+\))\s*(.*)$', line)
            if m:
                if current_subentry is None:
                    add_sense()
                    current_sense = {'index': m.group(1), 'meaning': m.group(2).strip(), 'examples': []}
                else:
                    # treat as part of subentry meaning if it occurs
                    current_subentry['meaning'] += "\n" + line
            else:
                # unnumbered or continuation of previous meaning OR example
                target_dict = current_subentry if current_subentry is not None else current_sense
                if target_dict is None:
                    current_sense = {'index': '', 'meaning': line, 'examples': []}
                else:
                    if target_dict['examples']:
                        # Continuation of the last example's translation
                        target_dict['examples'][-1]['zh'] += "\n" + line
                    elif target_dict['meaning']:
                        target_dict['meaning'] += "\n" + line
                    else:
                        target_dict['meaning'] = line

    add_sense()
    add_subentry()
    
    return {
        'kana': kana,
        'category': category,
        'senses': senses,
        'subentries': subentries
    }

def dict_to_xml(parsed):
    xml = ['<entry>']
    
    head = parsed.get('kana', '')
    
    xml.append(f'  <headword>{escape(head)}</headword>')
    if parsed.get('category'):
        xml.append(f'  <category>{escape(parsed.get("category"))}</category>')
        
    if parsed.get('senses'):
        xml.append('  <senses>')
        for sense in parsed['senses']:
            idx_attr = f' index="{sense["index"]}"' if sense["index"] else ''
            xml.append(f'    <sense{idx_attr}>')
            if sense['meaning']:
                xml.append(f'      <meaning>{escape(sense["meaning"])}</meaning>')
            if sense['examples']:
                xml.append('      <examples>')
                for eg in sense['examples']:
                    xml.append('        <example>')
                    xml.append(f'          <ja>{escape(eg["ja"])}</ja>')
                    if eg["zh"]:
                        xml.append(f'          <zh>{escape(eg["zh"])}</zh>')
                    xml.append('        </example>')
                xml.append('      </examples>')
            xml.append('    </sense>')
        xml.append('  </senses>')
        
    if parsed.get('subentries'):
        xml.append('  <subentries>')
        for sub in parsed['subentries']:
            xml.append('    <subentry>')
            xml.append(f'      <headword>{escape(sub["headword"])}</headword>')
            if sub['meaning']:
                 xml.append(f'      <meaning>{escape(sub["meaning"])}</meaning>')
            if sub['examples']:
                xml.append('      <examples>')
                for eg in sub['examples']:
                    xml.append('        <example>')
                    xml.append(f'          <ja>{escape(eg["ja"])}</ja>')
                    if eg["zh"]:
                        xml.append(f'          <zh>{escape(eg["zh"])}</zh>')
                    xml.append('        </example>')
                xml.append('      </examples>')
            xml.append('    </subentry>')
        xml.append('  </subentries>')
        
    xml.append('</entry>')
    return '\n'.join(xml)

def write_mdx_source(json_file, output_txt_path):
    with open(json_file, 'r', encoding='utf-8') as f:
        words = json.load(f)
    # 打开输出文件准备写入
    with open(output_txt_path, 'w', encoding='utf-8') as f_out:
        
        # 遍历JSON数据中的每一个词条
        for word in words:
            if not word['headword']:
                continue
            headword = word['headword']
            xml = '<link rel="stylesheet" href="XRHNSCNTC.css" />'
            xml += word['xml']
            expanded_words = word.get('expanded_words',[])

            f_out.write(headword + '\n')
            f_out.write(xml + '\n')
            f_out.write('</>\n')

            for expanded_word in expanded_words:
                expanded_word = expanded_word.strip()
                f_out.write(expanded_word + '\n')
                f_out.write(f'@@@LINK={headword}\n')
                f_out.write('</>\n')

def main():
    sys.stdout.reconfigure(encoding='utf-8')
    input_file = '新日汉拟声拟态词词典_left.json'
    output_file = '新日汉拟声拟态词词典_parsed.json'
    
    with open(input_file, 'r', encoding='utf-8') as f:
        data = json.load(f)
        
    for item in data:
        headword_original = item.get('headword', '')
        parsed = parse_text(item['text'], headword_original)
        
        # Merge parsed fields to the item directly as requested:
        item['headword_parsed'] = parsed['kana']
        item['category'] = parsed['category']
        item['senses'] = parsed['senses']
        item['subentries'] = parsed['subentries']
        
        item['xml'] = dict_to_xml(parsed)
        
    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
        
    print(f"Successfully processed {len(data)} entries. Output text to {output_file}")
    write_mdx_source(output_file, '新日汉拟声拟态词词典.mdx.txt')

if __name__ == '__main__':
    main()
