#!/usr/bin/env python3
"""Fix 021301/021401/021501/021701: fill ability + explanation, add empty second block"""
import requests, json, time

APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf"
APP_ID = "cli_a931175d41799cc7"
APP_SECRET = "Iw2vEfbjT6GtV0GhbxbZqfQ4nAPtbR14"
TABLE = "tblRGv7k4WH58Jgq"

def get_token():
    r = requests.post("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
        json={"app_id": APP_ID, "app_secret": APP_SECRET}, timeout=10)
    return r.json()["tenant_access_token"]

token = get_token()

# Fetch records
r = requests.get(f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE}/records?page_size=200",
    headers={"Authorization": f"Bearer {token}"}, timeout=15)

records = {}
for it in r.json()["data"]["items"]:
    qsid = it["fields"].get("题目集合 ID", "")
    if qsid in ("021301", "021401", "021501", "021701"):
        records[qsid] = {
            "rid": it["record_id"],
            "jd": json.loads(it["fields"].get("jsonData", "{}"))
        }

# ========== 021301 - 描述人物与自己 ==========
fixes_021301 = {
    "first": {
        0: {"ability": ["基础信息表达｜个人信息问答"],
            "explanation": "本题考察用英语描述他人外貌的能力。回答时用 'He/She has...' 或 'My best friend is...' 描述身高、头发、眼睛等特征。例如 'She has long black hair and big brown eyes.'"},
        1: {"ability": ["基础信息表达｜个人信息问答"],
            "explanation": "本题考察用英语描述家人特征的能力。回答时用 'My dad/mom is...' 开始，描述外貌或性格，例如 'My mom is kind and she always smiles.'"},
        2: {"ability": ["基础信息表达｜个人信息问答"],
            "explanation": "本题考察表达个人能力。回答用 'I am good at...' 或 'I can... well'，例如 'I am good at drawing pictures for my friends.'"},
        3: {"ability": ["基础信息表达｜个人信息问答"],
            "explanation": "本题考察描述家人角色。回答时说明谁帮助你及如何帮助，例如 'My grandma is good at helping me — she always makes my favourite food.'"},
    }
}

# ========== 021401 - 条件场景与应对 ==========
fixes_021401 = {
    "first": {
        0: {"ability": ["互动应答｜问答交流"],
            "explanation": "本题考察在特定情境下用英语礼貌询问的能力。回答时用 'I will ask...' 或 'Excuse me...' 开头，例如 'I will ask the teacher, \"When is the school trip?\"'"},
        1: {"ability": ["互动应答｜问答交流"],
            "explanation": "本题考察主动提供帮助的英语表达。回答用 'I will say...' 或 'Do you need...?'，例如 'I will say, \"Do you need any help? Let me carry some for you.\"'"},
        2: {"ability": ["互动应答｜问答交流"],
            "explanation": "本题考察用英语提醒他人遵守规则。回答用 'I will say...' 和礼貌的语气，例如 'I will say, \"Please don't run in the library — someone could get hurt.\"'"},
        3: {"ability": ["基础信息表达｜个人信息问答"],
            "explanation": "本题考察在问题情境下寻求帮助的表达。回答时说明应该联系谁及为什么，例如 'I should talk to a vet because they are animal doctors.'"},
    }
}

# ========== 021501 - 问题解决与安慰 ==========
fixes_021501 = {
    "first": {
        0: {"ability": ["互动应答｜问答交流"],
            "explanation": "本题考察在等待情境下给出建议的表达。回答用 'I will tell him...' 和安慰语气，例如 'I will say, \"Let's wait until the teacher is free. We can check later.\"'"},
        1: {"ability": ["互动应答｜问答交流"],
            "explanation": "本题考察提供解决方案的英语表达。回答说明你会怎么做，例如 'I can share my lunch with him, or ask the teacher if there is extra food.'"},
        2: {"ability": ["互动应答｜问答交流"],
            "explanation": "本题考察用英语安慰他人的能力。回答包含道歉回应和安抚语，例如 'I will say, \"It's okay — it was an accident. Let me help you clean it up.\"'"},
        3: {"ability": ["协商表达"],
            "explanation": "本题考察用英语协商和妥协的表达。回答用 'How about...?' 或 'Maybe we can...'，例如 'How about we watch your film this time, and next time we can watch mine?'"},
    }
}

# ========== 021701 - 购物与计划 ==========
fixes_021701 = {
    "first": {
        0: {"ability": ["表达计划"],
            "explanation": "本题考察用英语表达购物需求。回答用 'I need to buy...' 并列出物品，例如 'I need to buy some bread, milk, and apples at the supermarket.'"},
        1: {"ability": ["表达推测"],
            "explanation": "本题考察用英语推测和表达购买地点。回答用 'I think I can buy...' 或 'Maybe at...'，例如 'I think I can buy a new toy at the shop near our school.'"},
        2: {"ability": ["表达计划"],
            "explanation": "本题考察用未来时态描述家庭计划。回答用 'I think we will...' 或 'Maybe we will...'，例如 'I think my family will visit my grandparents this weekend.'"},
        3: {"ability": ["表达愿望"],
            "explanation": "本题考察用虚拟语气表达购物愿望。回答用 'If I could, I would buy...' 或 'I would choose...'，例如 'If I could buy one thing, I would choose a new bicycle.'"},
    }
}

fixes_map = {
    "021301": fixes_021301,
    "021401": fixes_021401,
    "021501": fixes_021501,
    "021701": fixes_021701,
}

# Apply fixes and write back
for qsid, fixes in fixes_map.items():
    rec = records[qsid]
    jd = rec["jd"]
    rid = rec["rid"]
    
    # Apply ability and explanation to first block
    for qi_str, fix in fixes.get("first", {}).items():
        qi = int(qi_str)
        qs = jd["first"].get("questionSet", [])
        if qi < len(qs):
            qs[qi]["ability"] = fix["ability"]
            qs[qi]["explanation"] = fix["explanation"]
    
    # Add empty second block (no questions, placeholder)
    if not jd.get("second") or not jd["second"].get("questionSet"):
        jd["second"] = {
            "type": "speaking_qa",
            "questionSetID": qsid,
            "questionSet": [],
            "ability": [],
            "explanation": ""
        }
    
    new_jd = json.dumps(jd, ensure_ascii=False)
    
    r = requests.put(
        f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE}/records/{rid}",
        headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
        json={"fields": {"jsonData": new_jd}}, timeout=15)
    code = r.json().get("code")
    if code == 0:
        print(f"[✅] {qsid}: ability+explanation填满4题, second块已补")
    else:
        print(f"[❌] {qsid}: {r.json().get('msg')}")
    time.sleep(0.3)

# Verify
print("\n=== 验证 ===")
r = requests.get(f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE}/records?page_size=200",
    headers={"Authorization": f"Bearer {token}"}, timeout=15)

for it in r.json()["data"]["items"]:
    qsid = it["fields"].get("题目集合 ID", "")
    if qsid not in ("021301", "021401", "021501", "021701"):
        continue
    jd = json.loads(it["fields"].get("jsonData", "{}"))
    all_ok = True
    for bn in ["first", "second"]:
        b = jd.get(bn, {})
        qs = b.get("questionSet", [])
        if bn == "second":
            has_block = bool(b)
            print(f"  {qsid} {bn}: {'存在' if has_block else '缺失'}, 题数={len(qs)}")
            continue
        for qi, q in enumerate(qs):
            ab = q.get("ability", [])
            expl = q.get("explanation", "")
            ok = bool(ab) and len(expl) > 20
            if not ok:
                all_ok = False
            print(f"  {qsid} [{qi}] ab={ab} expl={'✅' if ok else '❌'} ({len(expl)}字)")
    status = "✅" if all_ok else "❌"
    print(f"  => {status}\n")

print("完成")
