"""Finish a Level-4 book once all its OCR chunks exist:
  1. join the chunks into <book folder>/<book name>.md (next to the PDF), '# Page N' headings, pages separated by ---;
  2. download every extracted picture (/media/...) into <book folder>/assets/<media id>/ and link it as ./assets/...
Idempotent: pictures already on disk are not downloaded again.   python tools/l4_finalize.py [slug ...]"""
import os, re, sys, glob, requests
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from ocr_level4 import BOOKS, OUT, BASE, book_pdf, chunks

RX = re.compile(r"(!\[[^\]]*\]\()(/media/[^)\s]+)(\))")

# On pages with no printed text the OCR model sometimes invents a "Data Analysis / Statistical Tests" sheet,
# or returns an empty ```markdown``` block: both are replaced by a short note.
HALLU = re.compile(r"(?:```markdown\s*)?\| Table 1: Data Analysis.*?\*\*r = 0:\*\* No correlation\.?\s*(?:```)?", re.S)
EMPTY = re.compile(r"```markdown\s*```")
NOTE = "*(Page sans texte imprimé.)*"


def clean(text):
    return EMPTY.sub(NOTE, HALLU.sub(NOTE, text))


def finalize(slug):
    expected = [c[3] for c in chunks(slug)]
    missing = [p for p in expected if not os.path.exists(p)]
    if missing:
        return f"{slug}: {len(missing)} of {len(expected)} chunks still missing"
    folder = os.path.dirname(book_pdf(slug))
    name = os.path.splitext(os.path.basename(book_pdf(slug)))[0]
    text = "\n\n---\n\n".join(open(p, encoding="utf-8").read().strip() for p in expected) + "\n"
    s, got, fail = requests.Session(), 0, 0

    def fix(m):
        nonlocal got, fail
        sub = m.group(2)[len("/media/"):]                 # <media id>/page_N_img_M.ext — unique per chunk
        local = os.path.join(folder, "assets", *sub.split("/"))
        if not os.path.exists(local):
            try:
                r = s.get(BASE + m.group(2), timeout=60); r.raise_for_status()
                os.makedirs(os.path.dirname(local), exist_ok=True)
                with open(local, "wb") as f:
                    f.write(r.content)
                got += 1
            except Exception as e:
                fail += 1
                print("  picture failed:", m.group(2), e)
                return m.group(0)
        return m.group(1) + "./assets/" + sub + m.group(3)

    text = RX.sub(fix, clean(text))
    dst = os.path.join(folder, name + ".md")
    with open(dst, "w", encoding="utf-8") as f:
        f.write(text)
    pages = len(re.findall(r"(?m)^# Page \d+", text))
    return f"{slug}: {dst} — {pages} pages, {got} pictures downloaded, {fail} failed"


if __name__ == "__main__":
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")
    for slug in (sys.argv[1:] or BOOKS):
        print(finalize(slug), flush=True)
