#!/usr/bin/env python3
"""Audit all ELA weeks - silent load, comprehensive checks."""
import os, sys, subprocess, importlib.util, glob, io, contextlib

BASE = os.path.expanduser('~/Home_School/2nd_Grade/English_Language_Arts')
PAGE_TARGETS = {'Monday': 4, 'Tuesday': 3, 'Wednesday': 4, 'Thursday': 4, 'Friday': 3}

def get_words(mod):
    words = getattr(mod, 'WORDS', None)
    if words:
        return [w[0] if isinstance(w, tuple) else w for w in words]
    word_names = getattr(mod, 'WORD_NAMES', None)
    if word_names:
        return list(word_names)
    return None

def check_pages(week_dir):
    pages = {}
    for day in PAGE_TARGETS:
        pdfs = glob.glob(os.path.join(week_dir, day, '*.pdf'))
        if not pdfs:
            pages[day] = None
            continue
        r = subprocess.run(['pdfinfo', pdfs[0]], capture_output=True, text=True, timeout=5)
        for line in r.stdout.split('\n'):
            if line.startswith('Pages:'):
                pages[day] = int(line.split(':')[1].strip())
                break
    return pages

def word_coverage(text, words):
    if not text:
        return 0, []
    tl = text.lower()
    return len([w for w in words if w.lower() in tl]), [w for w in words if w.lower() not in tl]

def audit_week(week_num):
    week_dir = os.path.join(BASE, f"Week_{week_num:02d}")
    script = os.path.join(week_dir, f"generate_week{week_num}.py")
    if not os.path.exists(script):
        return f"Week {week_num:02d}: SKIP\n", 0
    
    issues = []
    
    # Load module silently
    old_stdout = sys.stdout
    old_stderr = sys.stderr
    sys.stdout = io.StringIO()
    sys.stderr = io.StringIO()
    try:
        sys.path.insert(0, BASE)
        spec = importlib.util.spec_from_file_location(f'gen{week_num}', script)
        mod = importlib.util.module_from_spec(spec)
        try:
            spec.loader.exec_module(mod)
        except SystemExit:
            pass  # Generator validation calls sys.exit - ignore
        words = get_words(mod)
    except Exception as e:
        sys.stdout = old_stdout
        sys.stderr = old_stderr
        return f"Week {week_num:02d}: LOAD FAIL — {e}\n", 1
    finally:
        sys.stdout = old_stdout
        sys.stderr = old_stderr
    
    if not words:
        return f"Week {week_num:02d}: SKIP (no word list)\n", 0
    if len(words) != 12:
        issues.append(f"⚠ {len(words)} words (expected 12)")
    
    # Page counts
    pages = check_pages(week_dir)
    page_strs = []
    for day, target in PAGE_TARGETS.items():
        pc = pages.get(day)
        page_strs.append(f"{day}:{pc or 'X'}")
        if pc and pc != target:
            issues.append(f"📄 {day}: {pc}p (target {target})")
        elif not pc:
            issues.append(f"📄 {day}: no PDF")
    
    # Word coverage
    for attr in ['MONDAY_STORY', 'THURSDAY_STORY', 'FRIDAY_REVIEW_STORY']:
        text = getattr(mod, attr, '')
        if not text:
            continue
        cnt, miss = word_coverage(text, words)
        if cnt < 12:
            lbl = attr.replace('_', ' ').title()
            issues.append(f"📖 {lbl}: {cnt}/12 (missing: {', '.join(miss[:4])})")
    
    # Swap words
    for attr in ['TUESDAY_SWAP_DATA', 'THURSDAY_SWAP_DATA']:
        sd = getattr(mod, attr, [])
        for i, item in enumerate(sd):
            if isinstance(item, tuple) and len(item) >= 3:
                for pair in item[1:]:
                    if isinstance(pair, tuple):
                        for w in pair:
                            if w not in words:
                                issues.append(f"🔄 {attr}[{i}]: '{w}' not in words")
    
    # Monday sort
    sa = getattr(mod, 'TEACHER_MONDAY_SORT_ANSWERS', None)
    if isinstance(sa, dict):
        all_s = []
        for wl in sa.values():
            all_s.extend(wl)
        if set(all_s) != set(words):
            miss = set(words) - set(all_s)
            extra = set(all_s) - set(words)
            if miss: issues.append(f"📊 Sort missing: {miss}")
            if extra: issues.append(f"📊 Sort extra: {extra}")
    
    # Pattern hunt
    ph = getattr(mod, 'TUESDAY_PATTERN_HUNT_WORDS', None)
    if ph and len(ph) == 12 and all(w in words for w in ph):
        issues.append("🔍 Pattern hunt: no decoys")
    
    # Correct sentences
    for sent in getattr(mod, 'WEDNESDAY_CORRECT', []):
        if sent and sent[0].isupper():
            issues.append(f"✏️ Already capitalized: '{sent[:35]}...'")
    
    # Fill mismatch
    f1 = getattr(mod, 'MONDAY_FILL_DATA', None)
    g1 = getattr(mod, 'TEACHER_MONDAY_FILL_ANSWERS', None)
    if f1 and g1:
        try:
            if [a for _, a in f1] != g1:
                issues.append("📝 Monday fill mismatch")
        except: pass
    
    fw = getattr(mod, 'WEDNESDAY_FILL', None)
    gw = getattr(mod, 'TEACHER_WEDNESDAY_FILL_ANSWERS', None)
    if fw and gw:
        try:
            if [a for _, a in fw] != gw:
                issues.append("📝 Wednesday fill mismatch")
        except: pass
    
    # Paragraph label
    pd = getattr(mod, 'WEDNESDAY_PARAGRAPH_LABEL_DATA', [])
    pa = getattr(mod, 'TEACHER_WEDNESDAY_PARAGRAPH_LABEL_ANSWERS', [])
    if pd and pa and len(pd) != len(pa):
        issues.append(f"📋 Para label mismatch: {len(pd)} vs {len(pa)}")
    
    return f"Week {week_num:02d}: {'✓ PASS' if not issues else f'✗ {len(issues)} issues'} [{', '.join(page_strs)}]\n" + \
           ''.join(f"  • {i}\n" for i in issues), len(issues)

# Run
print("=" * 55)
print("ELA COURSE AUDIT — ALL 20 WEEKS")
print("=" * 55)

total = 0
passes = fails = skips = 0
for w in range(1, 21):
    report, n = audit_week(w)
    print(report, end='')
    lines = report.strip().split('\n')[0]
    if 'SKIP' in lines: skips += 1
    elif 'PASS' in lines: passes += 1
    else: fails += 1
    total += n

print("=" * 55)
print(f"PASS: {passes}  FAIL: {fails}  SKIP: {skips}")
print(f"Total issues: {total}")