#!/usr/bin/env python3
"""
口语-P4-看图识物 调整：统一5题/组 + 审校结果写入
"""
import json, subprocess

TOKEN = subprocess.run([
    'curl', '-s', '-X', 'POST',
    'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
    '-H', 'Content-Type: application/json',
    '-d', json.dumps({'app_id':'cli_a931175d41799cc7','app_secret':'Iw2vEfbjT6GtV0GhbxbZqfQ4nAPtbR14'})
], capture_output=True, text=True)
TOKEN = json.loads(TOKEN.stdout)['tenant_access_token']

APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf"
TABLE_ID = "tblsD2dxaRpLmkXD"

def update_record(rid, fields):
    body = json.dumps({"fields": fields}, ensure_ascii=False)
    r = subprocess.run([
        'curl', '-s', '-X', 'PUT',
        f'https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records/{rid}',
        '-H', f'Authorization: Bearer {TOKEN}',
        '-H', 'Content-Type: application/json',
        '-d', body
    ], capture_output=True, text=True)
    return json.loads(r.stdout)

def build_explanation(q_text, img_desc, word, is_color):
    if is_color:
        return (
            f"回答要点: {q_text}\n"
            f"图片内容: {img_desc}\n"
            f"考察能力: 图文匹配\n"
            f"评估标准: 语音语调准确性、语言流利度、内容完整性与相关性、语法准确性\n"
            f"回答指导: 鼓励学生用完整句子作答，如\"It's {word}.\"，根据图片颜色准确说出对应的颜色单词"
        )
    else:
        return (
            f"回答要点: {q_text}\n"
            f"图片内容: {img_desc}\n"
            f"考察能力: 图文匹配\n"
            f"评估标准: 语音语调准确性、语言流利度、内容完整性与相关性、语法准确性\n"
            f"回答指导: 鼓励学生用完整句子作答，如\"It's a {word}.\"，根据图片内容准确说出对应的英文单词"
        )

def build_short_exp(img_desc, word, is_color):
    obj = img_desc.replace('白色的背景，', '').rstrip('。')
    if is_color:
        return f'{obj}，对应的颜色单词是 {word}。'
    else:
        return f'{obj}，对应的英文单词是 {word}。'

def build_human_config(qsid, asr_prompt, questions, text_title="Look and answer."):
    lines = [f"做题要求：{text_title}", "", f"热词：", asr_prompt, "", "问题："]
    for i, q in enumerate(questions, 1):
        lines.append(f"{i}. ")
        lines.append(f"图片：{q['imageDesc']}")
        lines.append(f"题目：{q['question']}")
        lines.append(f"能力：{'、'.join(q['ability'])}")
        lines.append(f"解析：{q['shortExplanation']}")
        lines.append("")
    return "\n".join(lines)

def build_qs(qsid, words, image_descs, question_types, img_start):
    """question_types: list of (is_color_bool, question_text_override_or_None)"""
    qs = []
    for i, word in enumerate(words):
        is_color, q_override = question_types[i] if i < len(question_types) else (False, None)
        if q_override:
            q_text = q_override
            is_color = False
        elif is_color:
            q_text = "What colour is it?"
        else:
            q_text = "What's this?"
        
        q_img = f"{qsid}-{img_start + i:02d}.png"
        img_desc = image_descs[i]
        explanation = build_explanation(q_text, img_desc, word, is_color)
        short_exp = build_short_exp(img_desc, word, is_color)
        qs.append({
            "question": q_text,
            "questionImage": q_img,
            "imageDesc": img_desc,
            "ability": ["图文匹配"],
            "explanation": explanation,
            "shortExplanation": short_exp,
        })
    return qs

# ============================================================
# ID: 100001 — first=6→5 (drop purple), second=5 (no change)
# ============================================================
qsid = "100001"
first_words = ["blue", "red", "pink", "green", "orange"]
first_descs = [
    "白色的背景，中间是一颗蓝色的星星。",
    "白色的背景，中间是一个红色的气球。",
    "白色的背景，中间是一朵粉红色的花。",
    "白色的背景，中间是一片绿色的叶子。",
    "白色的背景，中间是一个橙色的橘子。",
]
first_qtypes = [(True, None)] * 5
first_questions = build_qs(qsid, first_words, first_descs, first_qtypes, 0)

second_words = ["bag", "dress", "jacket", "hat", "T-shirt"]
second_descs = [
    "白色的背景，中间是一个书包。",
    "白色的背景，中间是一条连衣裙。",
    "白色的背景，中间是一件夹克衫。",
    "白色的背景，中间是一顶帽子。",
    "白色的背景，中间是一件T恤衫。",
]
second_qtypes = [(False, None)] * 5
second_questions = build_qs(qsid, second_words, second_descs, second_qtypes, 5)

first_qs_obj = {
    "category": "speaking", "type": "speaking_pic_recognize",
    "asrPrompt": ", ".join(first_words), "questionSetID": qsid,
    "textTitle": "Look and answer.",
    "questionSet": [{k: v for k, v in q.items() if k != "shortExplanation"} for q in first_questions],
}
second_qs_obj = {
    "category": "speaking", "type": "speaking_pic_recognize",
    "asrPrompt": ", ".join(second_words), "questionSetID": qsid,
    "textTitle": "Look and answer.",
    "questionSet": [{k: v for k, v in q.items() if k != "shortExplanation"} for q in second_questions],
}

json_data = json.dumps({"first": first_qs_obj, "second": second_qs_obj}, ensure_ascii=False)
config1 = build_human_config(qsid, ", ".join(first_words), first_questions)
config2 = build_human_config(qsid, ", ".join(second_words), second_questions)

fields = {
    "jsonData": json_data,
    "题目1 完整配置": config1,
    "题目2 完整配置": config2,
    "审校结果": "✅ OK | 2026-05-18 小研审校",
}
resp = update_record("recvjYhcXkYXIM", fields)
print(f"100001: code={resp.get('code')} | first={len(first_words)} second={len(second_words)}")

# ============================================================
# ID: 110101 — first=6→5 (drop monster), second=6→5 (drop duplicate colour)
# ============================================================
qsid = "110101"
first_words = ["hair", "eye", "nose", "foot", "hand"]
first_descs = [
    "白色的背景，中间是一个人的头发。",
    "白色的背景，中间是一只眼睛。",
    "白色的背景，中间是一个鼻子。",
    "白色的背景，中间是一只脚。",
    "白色的背景，中间是一只手。",
]
first_qtypes = [(False, None)] * 5
first_questions = build_qs(qsid, first_words, first_descs, first_qtypes, 0)

second_words = ["black", "brown", "colour", "white", "yellow"]
second_descs = [
    "白色的背景，中间是一只黑色的猫。",
    "白色的背景，中间是一只棕色的小狗。",
    "白色的背景，中间是一个彩色的调色盘。",
    "白色的背景，中间是一只白色的兔子。",
    "白色的背景，中间是一朵黄色的向日葵。",
]
# colour is not a color answer → use "What's this?"
second_qtypes = [
    (True, None),   # black
    (True, None),   # brown
    (False, "What's this?"),  # colour — 颜色概念
    (True, None),   # white
    (True, None),   # yellow
]
second_questions = build_qs(qsid, second_words, second_descs, second_qtypes, 5)

first_qs_obj = {
    "category": "speaking", "type": "speaking_pic_recognize",
    "asrPrompt": ", ".join(first_words), "questionSetID": qsid,
    "textTitle": "Look and answer.",
    "questionSet": [{k: v for k, v in q.items() if k != "shortExplanation"} for q in first_questions],
}
second_qs_obj = {
    "category": "speaking", "type": "speaking_pic_recognize",
    "asrPrompt": ", ".join(second_words), "questionSetID": qsid,
    "textTitle": "Look and answer.",
    "questionSet": [{k: v for k, v in q.items() if k != "shortExplanation"} for q in second_questions],
}

json_data = json.dumps({"first": first_qs_obj, "second": second_qs_obj}, ensure_ascii=False)
config1 = build_human_config(qsid, ", ".join(first_words), first_questions)
config2 = build_human_config(qsid, ", ".join(second_words), second_questions)

fields = {
    "jsonData": json_data,
    "题目1 完整配置": config1,
    "题目2 完整配置": config2,
    "审校结果": "✅ OK | 2026-05-18 小研审校",
}
resp = update_record("recvjYhdvUxDgs", fields)
print(f"110101: code={resp.get('code')} | first={len(first_words)} second={len(second_words)}")

# ============================================================
# ID: 110201 — first=6→5 (move ice cream to second), second=4→5
# ============================================================
qsid = "110201"
first_words = ["bread", "pie", "cake", "candy", "chocolate"]
first_descs = [
    "白色的背景，中间是一片面包。",
    "白色的背景，中间是一块馅饼。",
    "白色的背景，中间是一块蛋糕。",
    "白色的背景，中间是一颗糖果。",
    "白色的背景，中间是一块巧克力。",
]
first_qtypes = [(False, None)] * 5
first_questions = build_qs(qsid, first_words, first_descs, first_qtypes, 0)

second_words = ["cat", "dog", "mice", "mouse", "ice cream"]
second_descs = [
    "白色的背景，中间是一只猫。",
    "白色的背景，中间是一只狗。",
    "白色的背景，中间是两只老鼠。",
    "白色的背景，中间是一只老鼠。",
    "白色的背景，中间是一个冰淇淋。",
]
second_qtypes = [
    (False, None),              # cat
    (False, None),              # dog
    (False, "What are these?"), # mice (plural)
    (False, None),              # mouse
    (False, None),              # ice cream
]
second_questions = build_qs(qsid, second_words, second_descs, second_qtypes, 5)

first_qs_obj = {
    "category": "speaking", "type": "speaking_pic_recognize",
    "asrPrompt": ", ".join(first_words), "questionSetID": qsid,
    "textTitle": "Look and answer.",
    "questionSet": [{k: v for k, v in q.items() if k != "shortExplanation"} for q in first_questions],
}
second_qs_obj = {
    "category": "speaking", "type": "speaking_pic_recognize",
    "asrPrompt": ", ".join(second_words), "questionSetID": qsid,
    "textTitle": "Look and answer.",
    "questionSet": [{k: v for k, v in q.items() if k != "shortExplanation"} for q in second_questions],
}

json_data = json.dumps({"first": first_qs_obj, "second": second_qs_obj}, ensure_ascii=False)
config1 = build_human_config(qsid, ", ".join(first_words), first_questions)
config2 = build_human_config(qsid, ", ".join(second_words), second_questions)

fields = {
    "jsonData": json_data,
    "题目1 完整配置": config1,
    "题目2 完整配置": config2,
    "审校结果": "✅ OK | 2026-05-18 小研审校",
}
resp = update_record("recvjYhe4opOGm", fields)
print(f"110201: code={resp.get('code')} | first={len(first_words)} second={len(second_words)}")

# ============================================================
# VERIFY ALL
# ============================================================
print("\n=== VERIFICATION ===")
for qsid, rid in [("100001","recvjYhcXkYXIM"),("110101","recvjYhdvUxDgs"),("110201","recvjYhe4opOGm")]:
    r = subprocess.run([
        'curl', '-s', '-X', 'GET',
        f'https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records/{rid}',
        '-H', f'Authorization: Bearer {TOKEN}'
    ], capture_output=True, text=True)
    f = json.loads(r.stdout)['data']['record']['fields']
    jd = json.loads(f['jsonData'])
    f_count = len(jd['first']['questionSet'])
    s_count = len(jd['second']['questionSet'])
    review = f.get('审校结果', 'N/A')
    
    issues = []
    if f_count != 5: issues.append(f"first={f_count}≠5")
    if s_count != 5: issues.append(f"second={s_count}≠5")
    if not review: issues.append("missing review")
    
    # Spot check: explanations are Chinese
    for sec_name, sec in [("first", jd['first']), ("second", jd['second'])]:
        for qi, q in enumerate(sec['questionSet']):
            exp = q.get('explanation','')
            if not any('\u4e00' <= c <= '\u9fff' for c in exp):
                issues.append(f"{sec_name}Q{qi} explanation not Chinese")
    
    status = '✅' if not issues else '❌'
    print(f"{status} {qsid}: first={f_count} second={s_count} review={review}")
    if issues:
        for iss in issues:
            print(f"   ❌ {iss}")

print("\n✅ VERIFICATION COMPLETE")
