"""Pull the 0-10 scores and the concrete criticisms out of every answer of a round, then average them the way
round 2 did (averages.json: ALL / per model / per model+kind; each value is [mean, count]).

  python3 _ref/ai-eval/score_round.py <round_dir> [--prev 2026-09-25-r2]

Extraction runs one `claude -p` per answer and asks for JSON only. A score the answer did not give stays null
(never guessed). Output: <round_dir>/scores.json and <round_dir>/averages.json.
"""
import concurrent.futures as cf
import json
import os
import re
import subprocess
import sys

HERE = os.path.dirname(os.path.abspath(__file__))
KEYS = ['trust', 'portfolio', 'real_software', 'enterprise']
ASK = """Bên dưới là một câu trả lời của AI đánh giá công ty MONA Software. Trả về DUY NHẤT một JSON, không kèm chữ nào khác:
{"scores": {"trust": số|null, "portfolio": số|null, "real_software": số|null, "enterprise": số|null},
 "verdict": "1 câu tiếng Việt: kết luận chính của câu trả lời",
 "complaints": ["mỗi lời chê cụ thể nhắm vào MONA hoặc trang web, viết lại ngắn gọn bằng tiếng Việt, tối đa 12 mục"],
 "harsh_quotes": ["tối đa 5 câu gắt nhất, trích NGUYÊN VĂN từ câu trả lời"],
 "claims_to_check": ["tuyên bố/con số trên trang mà câu trả lời cho là cần kiểm chứng hoặc mâu thuẫn"]}
Quy tắc: điểm theo thang 0-10 đúng như câu trả lời chấm (trust = độ tin cậy, portfolio = sức mạnh portfolio,
real_software = có thật là công ty phần mềm, enterprise = sẵn sàng cho doanh nghiệp lớn). Câu trả lời không chấm tiêu chí
nào thì để null, tuyệt đối không tự đoán. Điểm dạng khoảng (vd 4-5) thì lấy trung bình.

<cau_tra_loi>
"""


def extract(path):
    txt = open(path, encoding='utf-8').read()
    body = txt.split('## Trả lời', 1)[-1]
    r = subprocess.run(['claude', '-p', '--output-format', 'text', '--tools', ''], input=ASK + body + '\n</cau_tra_loi>',
                       text=True, capture_output=True, timeout=600, cwd='/tmp')
    m = re.search(r'\{.*\}', r.stdout, re.S)
    try:
        d = json.loads(m.group(0))
    except Exception:
        d = {'scores': {k: None for k in KEYS}, 'error': r.stdout[:300]}
    name = os.path.basename(path)
    n = int(name[:2])
    d['file'] = name
    d['model'] = 'codex' if n <= 16 else ('claude' if n <= 32 else 'gpt55')
    d['kind'] = 'cold' if '-cold-' in name else 'page'
    return d


def avg(rows):
    out = {}
    for k in KEYS:
        v = [r['scores'].get(k) for r in rows if isinstance(r.get('scores'), dict) and isinstance(r['scores'].get(k), (int, float))]
        out[k] = [round(sum(v) / len(v), 2) if v else None, len(v)]
    return out


def averages(scores):
    groups = {'ALL': scores, 'paired (codex+claude)': [s for s in scores if s['model'] in ('codex', 'claude')]}
    for m in ('codex', 'claude', 'gpt55'):
        groups[m] = [s for s in scores if s['model'] == m]
        for k in ('page', 'cold'):
            groups[f'{m}/{k}'] = [s for s in scores if s['model'] == m and s['kind'] == k]
    return {g: avg(rows) for g, rows in groups.items() if rows}


def main():
    rd = os.path.abspath(sys.argv[1])
    files = sorted(os.path.join(rd, 'raw', f) for f in os.listdir(os.path.join(rd, 'raw')) if f.endswith('.md'))
    with cf.ThreadPoolExecutor(6) as ex:
        scores = list(ex.map(extract, files))
    json.dump(scores, open(os.path.join(rd, 'scores.json'), 'w'), ensure_ascii=False, indent=1)
    av = averages(scores)
    json.dump(av, open(os.path.join(rd, 'averages.json'), 'w'), ensure_ascii=False, indent=1)
    prev = sys.argv[sys.argv.index('--prev') + 1] if '--prev' in sys.argv else None
    old = json.load(open(os.path.join(HERE, prev, 'scores.json'))) if prev else None
    print(f'{len(scores)} answers, {sum(1 for s in scores if "error" in s)} extraction errors')
    for g, v in av.items():
        line = '  '.join(f'{k} {v[k][0]} ({v[k][1]})' for k in KEYS)
        print(f'{g:24s} {line}')
    if old:
        # round 2's scores.json names the kind "mode"; average it exactly like this round
        print(f'\n{prev} (same averaging):')
        for g, v in averages([dict(s, kind=s.get('kind') or s.get('mode', 'page')) for s in old]).items():
            print(f'{g:24s} ' + '  '.join(f'{k} {v[k][0]} ({v[k][1]})' for k in KEYS))


if __name__ == '__main__':
    main()
