#!/usr/bin/env python3
"""Fix broken sentences at page boundaries for chuan-muc-sadi-ver-2-clean.md
Pages 16-260 only. Merges broken last lines of page N into page N+1.
"""

import re
import sys

SRC = "/home/tuan-nguyen/.openclaw/workspace/002-cung-cach-sa-di/chuan-muc-sadi-ver-2-clean.md"

# ── Detection helpers ──────────────────────────────────────────────

def ends_properly(text: str) -> bool:
    """True if line looks like a natural sentence/page end."""
    t = text.strip()
    if not t:
        return True
    # Figure/image-only line
    if t in ('[ရုပ်ပုံ]', '[ ရုပ်ပုံ ]'):
        return True
    if t.startswith('[ရုပ်ပုံ:') or t.startswith('[ ရုပ်ပုံ :'):
        return True
    # Strip trailing brackets/parens/quotes
    cleaned = t
    while cleaned and cleaned[-1] in '])»)"\' \u200b':
        cleaned = cleaned[:-1].rstrip()
    # Myanmar sentence end
    if cleaned.endswith('။'):
        return True
    # Em-dash (natural colon-like break)
    if cleaned.endswith('—'):
        return True
    # Bold text ending (figure caption)
    if cleaned.endswith('**'):
        return True
    # Ellipsis → definitely broken
    if cleaned.endswith('…') or cleaned.endswith('...'):
        return False
    # Latin period
    if cleaned.endswith('.') and len(cleaned) > 1 and not cleaned[-2].isalpha():
        return True
    return False


def starts_structural(text: str) -> bool:
    """True if line starts a new section/table/list (not a continuation)."""
    t = text.strip()
    if not t:
        return True
    # Headers
    if re.match(r'^#{1,4}\s', t):
        return True
    # HR
    if t.startswith('---'):
        return True
    # Image/figure
    if re.match(r'^\[ရုပ်', t):
        return True
    # Bold section header (short)
    if re.match(r'^\*\*[^*]+\*\*', t) and len(t) < 100:
        return True
    # Table
    if t.startswith('|'):
        return True
    # Numbered list (Myanmar or Arabic)
    if re.match(r'^[၁-၉1-9][\)\.။\s]', t):
        return True
    # Bracketed list
    if re.match(r'^\([က-အ၁-၉1-9]+\)', t):
        return True
    # "အမှာ" note
    if t.startswith('**အမှာ'):
        return True
    # Exercise section
    if any(kw in t[:30] for kw in ('လေ့ကျင့်ခန်း', 'လေ့ကျင့်ခဏ်း', 'မေးခွန်း')):
        return True
    # Chapter section: ## (N) or ### (N)
    if re.match(r'^#{2,4}\s*\([၁-၉1-9]+\)', t):
        return True
    # Figure description (standalone)
    if t.startswith('ပြခဲ့သော') and 'နှင့်အညီ' in t[:50]:
        return True
    # "နိဂုံး" section
    if t.startswith('**နိဂုံး'):
        return True
    # "နမော တဿ" (homage - new section)
    if t.startswith('**နမော တဿ'):
        return True
    # Section headings like "### (က) ..."
    if re.match(r'^#{2,4}\s*\([က-အ]', t):
        return True
    # Standalone bold text that's clearly a header
    if re.match(r'^\*\*[^*]+\*\*$', t):
        return True
    return False


# ── Main ───────────────────────────────────────────────────────────

with open(SRC, 'r', encoding='utf-8') as f:
    lines = f.readlines()

# Locate all PAGE headers
page_headers = []  # (page_num, line_index)
for i, line in enumerate(lines):
    m = re.match(r'^## PAGE (\d+)', line.strip())
    if m:
        page_headers.append((int(m.group(1)), i))

# Build page objects
pages = []
for j, (pg, start) in enumerate(page_headers):
    end = page_headers[j + 1][1] if j + 1 < len(page_headers) else len(lines)
    pages.append({'num': pg, 'start': start, 'end': end})

# Detect broken boundaries
fixes = []  # (last_idx, first_idx, last_text, first_text, pg_n, pg_n1)
for k in range(len(pages) - 1):
    pg_n = pages[k]
    pg_n1 = pages[k + 1]

    if pg_n['num'] < 15 or pg_n1['num'] > 260:
        continue

    # Last content line of page N
    last_idx = None
    for idx in range(pg_n['end'] - 1, pg_n['start'], -1):
        s = lines[idx].strip()
        if s and not s.startswith('## PAGE'):
            last_idx = idx
            break

    # First content line of page N+1
    first_idx = None
    for idx in range(pg_n1['start'] + 1, pg_n1['end']):
        s = lines[idx].strip()
        if s and not s.startswith('## PAGE'):
            first_idx = idx
            break

    if last_idx is None or first_idx is None:
        continue

    last_text = lines[last_idx].strip()
    first_text = lines[first_idx].strip()

    if ends_properly(last_text) or starts_structural(first_text):
        continue

    fixes.append((last_idx, first_idx, last_text, first_text, pg_n['num'], pg_n1['num']))

print(f"Detected {len(fixes)} broken boundaries.")

# Process fixes from end to start (preserving indices)
for last_idx, first_idx, last_text, first_text, pg_n, pg_n1 in reversed(fixes):
    # Clean trailing ellipsis/dots
    clean_last = last_text.rstrip()
    clean_last = re.sub(r'[.…\s]+$', '', clean_last)
    clean_first = first_text.strip()

    # Dedup overlap (common suffix of clean_last = prefix of clean_first)
    overlap_len = 0
    max_ol = min(6, len(clean_last), len(clean_first))
    for ol in range(max_ol, 0, -1):
        if clean_last[-ol:] == clean_first[:ol]:
            overlap_len = ol
            break

    if overlap_len > 0:
        merged = clean_last + clean_first[overlap_len:]
    else:
        merged = clean_last + ' ' + clean_first

    # Verify we don't exceed reasonable length
    if len(merged) > 2000:
        print(f"  WARN: P{pg_n}→{pg_n1} merged line is {len(merged)} chars")

    # Remove broken line from page N
    del lines[last_idx]
    # Adjust first_idx if it was after last_idx
    actual_first = first_idx
    if first_idx > last_idx:
        actual_first = first_idx - 1
    # Replace first content line of page N+1 with merged
    lines[actual_first] = merged + '\n'

# Write output
with open(SRC, 'w', encoding='utf-8') as f:
    f.writelines(lines)

print(f"Fixed {len(fixes)} boundaries. Output written to {SRC}")

# Summary of fixes
for last_idx, first_idx, last_text, first_text, pg_n, pg_n1 in fixes:
    print(f"  P{pg_n}→{pg_n1}: ", end="")
    print(f"[...{last_text[-50:]}] + [{first_text[:50]}...]")
