#!/usr/bin/env python3
"""Generate explanations for 171 empty speaking-P1 questions, then write back."""
import json, requests, 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"]


# ── Explanation generator ──
# Map ability → template function that takes (question_content, ability_list) → explanation

def gen_expl(q, abilities):
    """Generate a natural Chinese explanation for a speaking question."""
    content = q.get('content', '') or q.get('question', '')
    ab = abilities[0] if abilities else '通用问答'
    
    # ── Pattern-based explanations ──
    
    # 基础信息表达｜个人信息问答
    if '个人信息' in ab:
        if 'name' in content.lower() or "what's your name" in content.lower():
            return "本题考察基础个人信息表达能力。回答时直接说出自己的名字，如 'My name is Tom.' 注意使用完整的介绍句式，发音清晰。"
        if 'old' in content.lower() and 'how' in content.lower():
            return "本题考察年龄表达。回答时用 'I am ... years old.' 的句式，说清楚数字。也可以补充生日信息使回答更丰富。"
        if 'from' in content.lower():
            return "本题考察国籍与家乡表达。回答时用 'I am from ...' 或 'I come from ...' 的句式，可以说国家或城市名称。"
        if 'live' in content.lower():
            return "本题考察家庭生活信息表达。回答时用 'I live with my ...' 描述同住的家人。注意家庭成员词汇的准确使用。"
        if 'hair' in content.lower() or 'look like' in content.lower() or 'wearing' in content.lower() or 'favourite clothes' in content.lower():
            return "本题考察人物外貌与穿着描述能力。回答时使用 'He/She has...' 描述发型发色，用 'He/She is wearing...' 描述衣着，注意颜色和衣物词汇的准确使用。"
        if 'schoolbag' in content.lower() or 'in your' in content.lower() and ('schoolbag' in content.lower() or 'desk' in content.lower() or 'classroom' in content.lower()):
            return "本题考察物品列举与位置描述能力。回答时使用 'There is/are ... in my ...' 句式，逐一说出物品名称，注意单复数一致。"
        if 'tall' in content.lower():
            return "本题考察比较级描述能力。回答时使用 '... is taller than me.' 的句式，说出比你高的人的名字。注意比较级的正确使用。"
        if 'dinosaur' in content.lower() or 'cloud' in content.lower() or 'moon' in content.lower():
            return "本题考察想象与外观描述能力。回答时使用形容词描述事物的样子，如 'It is big and green.' 或 'It looks like ...'，发挥想象力用英语表达。"
        if 'pet' in content.lower() and ('love' in content.lower() or 'like' in content.lower()):
            return "本题考察宠物喜好表达。回答时说出你喜欢的宠物，如 'I love dogs.' 并尝试说明喜欢的原因。注意动物名称词汇的准确使用。"
        if 'toy' in content.lower() or 'toys' in content.lower():
            return "本题考察个人物品表达。回答时列举你拥有的玩具，用 'I have ...' 句式。注意玩具词汇和复数形式的正确使用。"
        if 'book' in content.lower() and 'where' in content.lower():
            return "本题考察物品位置表达。回答时使用方位介词描述书的位置，如 'It is on the desk.' 或 'It is in my schoolbag.'"
        if 'pen' in content.lower() and 'yours' in content.lower():
            return "本题考察物品归属表达。肯定回答用 'Yes, it is mine.'，否定回答用 'No, it is not mine.' 注意物主代词的区分。"
        if 'goal' in content.lower():
            return "本题考察目标与计划表达能力。回答时说出本学期的目标，如 'My goal is to read 10 English books.' 注意使用完整句子表达决心。"
        if 'keep healthy' in content.lower() or 'health' in content.lower():
            return "本题考察健康建议表达能力。回答时列举保持健康的方法，如 'We can eat vegetables and exercise every day.' 注意使用情态动词 can/should。"
        # fallback for 个人信息
        return f"本题考察基础个人信息表达能力。回答时需要围绕「{content[:20]}」这个主题用完整的英语句子进行描述或说明，注意信息清晰、表达自然。"
    
    # 表达喜好与理由
    if '喜好' in ab:
        if 'favorite' in content.lower() or 'favourite' in content.lower():
            return "本题考察喜好表达与理由说明能力。回答时先明确说出喜好选择，如 'My favorite ... is ...'，然后用 'because' 或 'I like it because...' 说明理由。"
        if 'like' in content.lower() and 'music' in content.lower():
            return "本题考察音乐喜好表达。回答时说出你喜欢的音乐类型，如 'I like pop music.' 再说明原因如 'because it makes me happy.' 也可以举一首喜欢的歌为例。"
        if 'like' in content.lower() and 'read' in content.lower():
            return "本题考察阅读喜好表达。回答时说明你喜欢读什么类型的书，如 'I like story books.' 并补充阅读的感受或最喜欢的书籍。"
        if 'like' in content.lower() and 'internet' in content.lower():
            return "本题考察网络活动喜好表达。回答时说出你在网上喜欢做什么，如 'I like watching videos and playing games online.' 用 and 连接多项活动。"
        if 'like' in content.lower() and 'cat' in content.lower():
            return "本题考察原因解释能力。回答时用 'because' 引出原因，如 'I like cats because they are cute and soft.' 至少给出一个具体理由。"
        if 'hobby' in content.lower():
            return "本题考察爱好表达。回答时说出你的爱好，如 'My hobby is drawing.' 或 'I like playing football.' 可以补充做这个爱好的频率和感受。"
        if 'think of' in content.lower() or 'think about' in content.lower():
            return "本题考察观点表达能力。回答时用 'I think ...' 开头表达你的看法，然后简单说明原因。鼓励表达真实想法而不仅仅是正确回答。"
        if 'plan' in content.lower() or 'going to' in content.lower():
            return "本题考察未来计划表达能力。回答时用 'I plan to ...' 或 'I am going to ...' 的句式描述计划，注意将来时的正确使用。"
        if 'want to' in content.lower() and 'do' in content.lower():
            return "本题考察意愿与计划表达。回答时用 'I want to ...' 表达你想做的事，如果涉及周末计划可用 'I am going to ...'。"
        if 'dad' in content.lower() and ('unhappy' in content.lower() or 'say' in content.lower()):
            return "本题考察家庭情感与沟通表达。回答时描述爸爸的言行或情绪，如 'He said I should finish my homework first.' 注意引述和描述的准确性。"
        if 'happy' in content.lower() or 'glad' in content.lower():
            return "本题考察积极情感表达能力。回答时用 'I am happy/glad that ...' 的句式表达喜悦，并具体说出让你开心的事情。"
        if 'afraid' in content.lower():
            return "本题考察恐惧情感表达能力。回答时用 'I am afraid of ...' 说出害怕的动物或事物，可以简单说明原因如 'because it is scary.'"
        if 'need' in content.lower() or 'need to do' in content.lower():
            return "本题考察需求表达能力。回答时用 'I need to ...' 或 'We need ...' 说明需要做的事情或物品。注意 need 后接动词原形或名词。"
        if 'colour' in content.lower() or 'color' in content.lower():
            return "本题考察颜色偏好表达。回答时说出你想要的颜色，如 'I want the picture in blue.' 或 'I like red best.' 可以补充为什么喜欢这个颜色。"
        if 'whose' in content.lower():
            return "本题考察物品归属判断与表达。回答时用 'I think it is ...'s.' 或 'It might be ...' 的句式表达推断。注意名词所有格的正确使用。"
        if 'exam' in content.lower():
            return "本题考察学习准备与计划表达。回答时列举考前需做的事，如 'I need to review my notes and do more practice.' 注意使用 need to 表达必要性。"
        if 'wrong' in content.lower() and 'radio' in content.lower():
            return "本题考察推断与猜测表达能力。回答时用 'Maybe it is ...' 或 'It might be ...' 表达对故障原因的推测。注意情态动词 might/maybe 的使用。"
        return f"本题考察表达喜好与理由的能力。回答时先表明喜好态度或观点，再用 'because' 等连接词说明理由，注意使用完整的英语句子。"
    
    # 互动应答｜问答交流
    if '互动应答' in ab or '问答交流' in ab:
        if 'help' in content.lower() and 'say' in content.lower():
            return "本题考察礼貌应答能力。回答时给出得体的感谢用语，如 'Thank you so much!' 或 'That's very kind of you.' 注意感谢的真诚性表达。"
        if 'sorry' in content.lower() or 'lose' in content.lower() and 'book' in content.lower():
            return "本题考察道歉表达与情境应对。回答时用诚恳的道歉语如 'I am so sorry. I will help you find it.' 同时给出弥补方案，体现责任感。"
        if 'library' in content.lower() and 'should' in content.lower():
            return "本题考察规则表达能力。回答时使用情态动词如 'We shouldn't talk loudly.' 或 'We must be quiet.' 表达图书馆的行为规范。"
        if 'park' in content.lower() and ('must' in content.lower() or 'should' in content.lower()):
            return "本题考察规则与义务表达能力。回答时用 'We must not ...' 表达禁止行为，如 'We must not pick flowers or litter.' 注意 must 的使用。"
        if 'ill' in content.lower() or 'sad' in content.lower():
            return "本题考察共情与关怀表达能力。回答时说出关怀的话语，如 'I hope you feel better soon.' 或 'Don't be sad, let me help you.' 体现同理心。"
        if 'leave' in content.lower():
            return "本题考察礼貌告别用语。回答时说出得体的道别方式，如 'Goodbye!' 或 'See you later!' 也可以说 'It was nice meeting you.'"
        if 'friend comes' in content.lower() or 'friend came' in content.lower() or 'come to your home' in content.lower():
            return "本题考察接待与欢迎表达能力。回答时说出欢迎用语，如 'Welcome! Come in, please.' 或 'I'm so glad you came!' 注意热情友好的语气。"
        if 'introduce' in content.lower():
            return "本题考察介绍他人的能力。回答时使用 'This is my friend ...' 的句式介绍朋友，可以说出对方的名字和一两个特点。"
        if 'shop' in content.lower() or 'shopping' in content.lower():
            return "本题考察购物场景交流能力。回答时模拟店员用语如 'Can I help you?' 或 'What would you like to buy?' 注意服务场景的礼貌表达。"
        if 'swim' in content.lower() or 'sports' in content.lower():
            return "本题考察能力询问与应答。肯定回答用 'Yes, I can swim.'，否定回答用 'No, I can't swim.' 或补充 'But I can run fast.'"
        if 'can you help' in content.lower():
            return "本题考察请求帮助的表达与应答。回答时可以表示愿意帮助 'Sure, I will help you.' 或说明无法帮助的原因 'Sorry, my hands are full.'"
        if 'say when' in content.lower() and 'can' in content.lower() and 'find' in content.lower():
            return "本题考察失物求助表达。回答时说出寻找物品的请求语，如 'I can't find my pen. Can you help me?' 或 'Have you seen my pen?'"
        if 'say when' in content.lower() and 'ruler' in content.lower():
            return "本题考察借物请求表达。回答时说出礼貌的借物请求，如 'May I borrow your ruler, please?' 注意使用 May I 或 Can I 的礼貌表达。"
        if 'draw' in content.lower() and 'together' in content.lower():
            return "本题考察邀请与提议表达能力。回答时使用 'Let's draw together!' 或 'Shall we draw a picture?' 表达邀请，语气友好自然。"
        if 'loud' in content.lower():
            return "本题考察请求与协商表达能力。回答时礼貌地提出降低音量的请求，如 'Could you please turn it down?' 或 'It's a bit too loud.' 注意礼貌用语。"
        if 'rabbit' in content.lower() and 'eat' in content.lower():
            return "本题考察观察与描述应答。回答时描述兔子正在吃什么，如 'The rabbit is eating a carrot.' 注意现在进行时的正确使用。"
        if 'see in the sky' in content.lower():
            return "本题考察观察与描述应答。回答时描述天空中看到的事物，如 'I can see some birds and clouds.' 或 'I can see the sun.' 注意自然观察词汇。"
        if 'page' in content.lower():
            return "本题考察课堂指令应答能力。回答时说出应该翻到的页码，如 'Let's turn to page 10.' 或 'Please turn to page 10.'"
        if 'animal' in content.lower() and 'look at' in content.lower():
            return "本题考察选择与提议应答。回答时提出想看的动物，如 'Let's look at the elephants.' 或 'I want to see the monkeys.'"
        if 'car' in content.lower() and 'faster' in content.lower():
            return "本题考察比较与判断应答。回答时使用比较级说出哪辆车更快，如 'The red car is faster.' 注意比较级 -er 或 more 的使用。"
        if 'gift' in content.lower() or 'present' in content.lower():
            return "本题考察礼物相关表达能力。回答时描述想要的礼物或礼物送给谁，如 'I want a toy car for my birthday.' 或 'This gift is for my mum.'"
        if 'picnic' in content.lower():
            return "本题考察准备与计划描述能力。回答时列举野餐需要带的东西，如 'We need some sandwiches, fruit and drinks for the picnic.' 注意物品词汇的准确使用。"
        return f"本题考察互动应答能力。回答时需要根据「{content[:20]}」的情境，给出得体的英文回应，注意使用礼貌用语和完整句子。"
    
    # 信息交换｜双向问答
    if '信息交换' in ab:
        if 'lunch' in content.lower() or 'eat' in content.lower():
            return "本题考察饮食内容交流能力。回答时用 'Let's have ...' 提出午餐建议，或说出想吃的食物。注意食物名称词汇的准确使用，可以说明选择理由使交流更自然。"
        return "本题考察信息交换与双向交流能力。回答时不仅给出自己的答案，还可以反问对方以延续对话，注意问答之间的自然过渡和对话的互动性。"
    
    # 过去经历描述
    if '过去经历' in ab or 'Past' in ab:
        if 'see' in content.lower() and ('park' in content.lower() or 'weekend' in content.lower()):
            return "本题考察过去经历描述能力。回答时使用过去时描述你在公园看到的事物，如 'I saw many beautiful flowers and some ducks in the pond.' 注意过去式动词的正确使用。"
        if 'help' in content.lower():
            return "本题考察过去行为描述能力。回答时说出你帮助了谁以及怎么帮的，如 'I helped my mum clean the house.' 注意 help 后接动词原形。"
        if 'weekend' in content.lower():
            return "本题考察过去活动描述能力。回答时描述周末发生的事情，用过去时讲述活动和感受，如 'Last weekend, I went to the zoo with my family.'"
        return f"本题考察过去经历描述能力。回答时使用过去时态描述「{content[:20]}」相关经历，注意动词过去式的变化，包含时间、地点和感受。"
    
    # Fallback
    return f"本题考察英语口语应答能力。请围绕「{content[:30]}」用完整句子进行回答，注意发音清晰、语法正确、表达自然。"


# ── Main ──
def main():
    token = get_token()
    print("Token OK")
    
    with open('/root/.openclaw/workspace-xiaoyan/tmp/empty_expl_data.json') as f:
        records = json.load(f)
    
    print(f"Processing {len(records)} records, 171 questions...")
    
    updated = 0
    for rec in records:
        rid = rec['rid']
        jd = rec['jd']
        qsid = rec['qsid']
        
        modified = False
        for bn in ['first', 'second']:
            block = jd.get(bn, {})
            if not block:
                continue
            qs = block.get('questionSet', [])
            for qi, q in enumerate(qs):
                expl = q.get('explanation', '')
                if expl == 'PATCH' or not expl or len(expl.strip()) < 5:
                    abilities = q.get('ability', [])
                    new_expl = gen_expl(q, abilities)
                    q['explanation'] = new_expl
                    modified = True
                    updated += 1
        
        if modified:
            # Write back
            new_jd_str = 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_str}}, timeout=15)
            code = r.json().get('code')
            if code == 0:
                print(f'  ✅ {qsid} ({rid[:12]}...)')
            else:
                print(f'  ❌ {qsid}: {r.json().get("msg")}')
            time.sleep(0.25)
    
    print(f'\nDone: {updated} explanations generated across {len(records)} records')

if __name__ == '__main__':
    main()
