"""
Document-agnostic WB INS font verification script.
Compares each WB insertion's rPr against adjacent original runs in the same paragraph.
Works for any font (宋体, 仿宋, etc.) and any sz value.

Usage: python wb-ins-font-verify.py <docx_path>
Or import verify_wb_ins_fonts(path) → returns (issues: list[str], total: int)
"""
import zipfile, io, sys
from lxml import etree

def qn(tag):
    return '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}' + tag

def get_rpr_attrs(rpr):
    if rpr is None:
        return {'ea': None, 'ascii': None, 'hint': None, 'sz': None, 'bold': False}
    rfonts = rpr.find(qn('rFonts'))
    sz = rpr.find(qn('sz'))
    b = rpr.find(qn('b'))
    return {
        'ea': rfonts.get(qn('eastAsia')) if rfonts is not None else None,
        'ascii': rfonts.get(qn('ascii')) if rfonts is not None else None,
        'hint': rfonts.get(qn('hint')) if rfonts is not None else None,
        'sz': sz.get(qn('val')) if sz is not None else None,
        'bold': b is not None,
    }

def verify_wb_ins_fonts(docx_path):
    with open(docx_path, 'rb') as f:
        raw = f.read()
    with zipfile.ZipFile(io.BytesIO(raw)) as z:
        tree = etree.fromstring(z.read('word/document.xml'))
    body = tree.find(qn('body'))

    issues = []
    total = 0

    for p in body.findall(qn('p')):
        # Collect WB INS runs
        wb_runs = []
        for ins in p.findall('.//' + qn('ins')):
            if ins.get(qn('author')) != 'WB':
                continue
            for r in ins.findall(qn('r')):
                t = r.find(qn('t'))
                if t is not None and (t.text or '').strip():
                    wb_runs.append((t.text[:50], r))

        if not wb_runs:
            continue

        # Collect original (non-tracked) runs for comparison
        orig_attrs = None
        for r in p.findall(qn('r')):
            parent = r.getparent()
            if parent.tag in [qn('ins'), qn('del')]:
                continue
            t = r.find(qn('t'))
            if t is not None and (t.text or '').strip():
                orig_attrs = get_rpr_attrs(r.find(qn('rPr')))
                break

        for text, r in wb_runs:
            total += 1
            wb = get_rpr_attrs(r.find(qn('rPr')))

            # Font name check: must have eastAsia and ascii set (not None)
            if wb['ea'] is None:
                issues.append(f"MISSING eastAsia: '{text}'")
            if wb['ascii'] is None:
                issues.append(f"MISSING ascii: '{text}'")
            if wb['hint'] != 'eastAsia':
                issues.append(f"MISSING hint=eastAsia: '{text}'")
            if wb['sz'] is None:
                issues.append(f"MISSING sz: '{text}'")

            # Cross-check with original runs in same paragraph
            if orig_attrs and orig_attrs['ea']:
                if wb['ea'] and wb['ea'] != orig_attrs['ea']:
                    issues.append(f"FONT MISMATCH: '{text}' wb={wb['ea']} orig={orig_attrs['ea']}")
                if wb['sz'] and orig_attrs['sz'] and wb['sz'] != orig_attrs['sz']:
                    issues.append(f"SIZE MISMATCH: '{text}' wb={wb['sz']} orig={orig_attrs['sz']}")

    return issues, total

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python wb-ins-font-verify.py <docx_path>")
        sys.exit(1)
    issues, total = verify_wb_ins_fonts(sys.argv[1])
    if issues:
        print(f"FAIL: {len(issues)} issues in {total} WB INS runs")
        for i in issues:
            print(f"  - {i}")
        sys.exit(1)
    else:
        print(f"PASS: all {total} WB INS runs font-consistent")
