#!/usr/bin/env python3
"""Fact, length and subject checks on a raw file: python check_emails.py raw/<tool>.md
Splits the ## Answer section into the three emails on lines that name email 1/2/3 (or Miguel/Sofia/Inês);
if it cannot split, it scores facts on the whole text and skips the length check."""
import re, sys
text = open(sys.argv[1], encoding="utf-8").read()
ans = text.split("\n## Answer", 1)[1] if "\n## Answer" in text else text
ans = ans.replace(" ", " ").replace(" ", " ").replace("–", "-").replace("—", "-")
FACTS = {
 1: {"invoice": r"QR-?2026-?0314", "412.60": r"412[.,]60", "due 20 Aug": r"20(th)?\s+(of\s+)?August|August\s+20", "reminder 28 Aug": r"28(th)?\s+(of\s+)?August|August\s+28", "2% waived by 30 Sep": r"(?=.*2\s?%)(?=.*(waiv|not (be )?charg|not add|drop|forgo|forget))(?=.*30(th)?\s+(of\s+)?September)"},
 2: {"12% from 1 Oct": r"12\s?%.*?(1(st)?\s+(of\s+)?October|October\s+1)|(1(st)?\s+(of\s+)?October|October\s+1).*?12\s?%", "6%": r"\b6\s?%", "from 1 Nov": r"1(st)?\s+(of\s+)?November|November\s+1", "3-week lead": r"(three|3)[- ]week", "other suppliers": r"other (supplier|option|source|producer)|elsewhere|look (around|at alternatives)"},
 3: {"order 10482": r"10482", "one bowl broken": r"(one|1|a) (of the )?bowls?.{0,40}(broken|damaged|arrived broken|cracked|smashed)|(broken|damaged|cracked|smashed).{0,20}bowl", "replacement Monday": r"replacement.{0,80}Monday|Monday.{0,80}replacement", "refund 24.90": r"24[.,]90", "keep packaging, no return": r"(keep|hold on ?to|hang on ?to) (the |your )?(original )?(packaging|box)"},
}
ANCHOR = {1: r"miguel|caf[eé] aurora|QR-?2026", 2: r"sofia|olaria|12\s?%", 3: r"in[eê]s|carvalho|10482"}
lines = ans.split("\n")
starts = {}
for i, l in enumerate(lines):
    m = re.match(r"^\s*(#+\s*)?(\*\*)?\s*(e-?mail|message)?\s*#?\s*\b(1|2|3|one|two|three)\b", l, re.I)
    if m:
        n = {"1":1,"2":2,"3":3,"one":1,"two":2,"three":3}[m.group(4).lower()]
        starts.setdefault(n, i)
if len(starts) < 3:
    starts = {}
    for i, l in enumerate(lines):
        if re.search(r"^\s*(\*\*)?subject", l, re.I):
            for n, a in ANCHOR.items():
                if n not in starts and re.search(a, "\n".join(lines[i:i+6]), re.I): starts[n] = i; break
chunks = {}
if len(starts) == 3:
    order = sorted(starts.items(), key=lambda kv: kv[1])
    for k, (n, i) in enumerate(order):
        j = order[k+1][1] if k+1 < len(order) else len(lines)
        chunks[n] = "\n".join(lines[i:j])
else:
    print("could not split into three emails; scoring facts on the whole text")
    chunks = {1: ans, 2: ans, 3: ans}
total = 0
for n in (1, 2, 3):
    c = chunks[n]
    ok = [k for k, rx in FACTS[n].items() if re.search(rx, c, re.I | re.S)]
    total += len(ok)
    subj = bool(re.search(r"^\s*(\*\*)?\s*subject\s*(\*\*)?\s*:", c, re.I | re.M))
    body = re.sub(r"^\s*(\*\*)?\s*subject.*$", "", c, flags=re.I | re.M)
    body = re.sub(r"^\s*(#+\s*)?(\*\*)?\s*(e-?mail)?\s*#?\s*\b(1|2|3|one|two|three)\b.*$", "", body, flags=re.I | re.M)
    body = re.sub(r"Ana,?\s*\n?\s*Quinta da Ribeira\s*$", "", body.strip(), flags=re.I)
    words = len(re.findall(r"\S+", body)) if len(starts) == 3 else None
    signed = bool(re.search(r"Ana,?\s*\n?\s*Quinta da Ribeira", c))
    print(f"email {n}: facts {len(ok)} of 5 -> missing {[k for k in FACTS[n] if k not in ok]} | subject: {subj} | words: {words} | signed: {signed}")
print(f"facts total: {total} of 15")
