"""
单元挑战 口语写作内容生产：10条记录（写作P1×4, 口语P1×4, 写作P2×1, 口语P2×1）
"""
import json, urllib.request

APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf"
CRED_FILE = "/root/.openclaw/credentials/xiaoyan/config.json"

TABLES = {
    "writing_email": "tblszuk1TeToofBF",
    "writing_picWrite": "tblSAwlMumKoyjws",
    "speaking_qa": "tblRGv7k4WH58Jgq",
    "speaking_topic": "tblGoWYBmVI0IrvQ",
}

RECORDS = []

# ====================================================================
# 写作-P1-011301: We need to..., Let me..., It's on fire!
# ====================================================================
RECORDS.append({
    "table": "writing_email", "sid": "011301", "type": "写作-P1",
    "json": {
        "first": {
            "category": "writing",
            "type": "writing_email",
            "questionSetID": "011301",
            "textDesc": "Your friend Mark saw smoke coming from a building. Write an email to help him know what to do.<br>Put these sentences in order to make a telling email.",
            "optionSetList": [
                "Dear Mark,",
                "We need to call for help at once.",
                "Let me check if anyone is still inside.",
                "It's on fire! Call 119 right away.",
                "Please stay safe and don't go too near the building.",
                "Best wishes, Your Friend"
            ],
            "answerSet": [0, 1, 2, 3, 4, 5],
            "ability": ["短消息写作｜邮件/便条", "衔接与连贯｜连词使用"],
            "explanation": "根据事件发生的时间逻辑排列句子顺序：先确认情况紧急，再行动呼救，确认安全后表达关心。此题考察邮件的格式规范和事件叙述的逻辑顺序。"
        },
        "second": {}
    },
    "t1": """【题目描述】
Your friend Mark saw smoke coming from a building. Write an email to help him know what to do.
Put these sentences in order to make a telling email.

【段落列表】
A. Dear Mark,
B. We need to call for help at once.
C. Let me check if anyone is still inside.
D. It's on fire! Call 119 right away.
E. Please stay safe and don't go too near the building.
F. Best wishes, Your Friend

【答案】
A, D, B, C, E, F

【解析】
根据事件发生的时间逻辑排列句子顺序：先确认情况紧急，再行动呼救，确认安全后表达关心。此题考察邮件的格式规范和事件叙述的逻辑顺序。

【能力项】
短消息写作｜邮件/便条，衔接与连贯｜连词使用""",
    "t2": ""
})

# ====================================================================
# 写作-P1-011401: ...promise..., We can't..., ...can take care of...
# ====================================================================
RECORDS.append({
    "table": "writing_email", "sid": "011401", "type": "写作-P1",
    "json": {
        "first": {
            "category": "writing",
            "type": "writing_email",
            "questionSetID": "011401",
            "textDesc": "Your friend Lily needs someone to take care of her puppy while she is away. Write an email to promise her you can help.<br>Put these sentences in order to make a proper reply.",
            "optionSetList": [
                "Dear Lily,",
                "I promise I will take good care of your puppy.",
                "We can't let the little one stay alone at home.",
                "My mom can take care of feeding time every morning.",
                "I will walk the puppy after school each day.",
                "Looking forward to seeing you! Best, Your Friend"
            ],
            "answerSet": [0, 1, 2, 3, 4, 5],
            "ability": ["短消息写作｜邮件/便条", "衔接与连贯｜连词使用"],
            "explanation": "按照邮件格式：问候→表达承诺→说明不能放任→描述照顾计划→结尾。考察日常承诺和安排说明的书面表达能力。"
        },
        "second": {}
    },
    "t1": """【题目描述】
Your friend Lily needs someone to take care of her puppy while she is away. Write an email to promise her you can help.
Put these sentences in order to make a proper reply.

【段落列表】
A. Dear Lily,
B. I promise I will take good care of your puppy.
C. We can't let the little one stay alone at home.
D. My mom can take care of feeding time every morning.
E. I will walk the puppy after school each day.
F. Looking forward to seeing you! Best, Your Friend

【答案】
A, B, C, D, E, F

【解析】
按照邮件格式：问候→表达承诺→说明不能放任→描述照顾计划→结尾。考察日常承诺和安排说明的书面表达能力。

【能力项】
短消息写作｜邮件/便条，衔接与连贯｜连词使用""",
    "t2": ""
})

# ====================================================================
# 写作-P1-011501: How can we...?, I think I found...!, This must be a...
# ====================================================================
RECORDS.append({
    "table": "writing_email", "sid": "011501", "type": "写作-P1",
    "json": {
        "first": {
            "category": "writing",
            "type": "writing_email",
            "questionSetID": "011501",
            "textDesc": "You and your friend are planning a surprise party for your teacher. Write an email to discuss the plan.<br>Put these sentences in order to make a clear message.",
            "optionSetList": [
                "Dear Friend,",
                "How can we make the surprise party really special?",
                "I think I found a perfect gift at the shop near school!",
                "This must be a secret, so don't tell anyone else.",
                "Let's meet after school tomorrow to talk more.",
                "Can't wait for the big day! Best, Your Friend"
            ],
            "answerSet": [0, 1, 2, 3, 4, 5],
            "ability": ["短消息写作｜邮件/便条", "衔接与连贯｜连词使用"],
            "explanation": "按照计划讨论的逻辑：问候→提问如何做→分享发现→提醒保密→约定讨论时间→表达期待。考察疑问句和计划表达在书面语中的应用。"
        },
        "second": {}
    },
    "t1": """【题目描述】
You and your friend are planning a surprise party for your teacher. Write an email to discuss the plan.
Put these sentences in order to make a clear message.

【段落列表】
A. Dear Friend,
B. How can we make the surprise party really special?
C. I think I found a perfect gift at the shop near school!
D. This must be a secret, so don't tell anyone else.
E. Let's meet after school tomorrow to talk more.
F. Can't wait for the big day! Best, Your Friend

【答案】
A, B, C, D, E, F

【解析】
按照计划讨论的逻辑：问候→提问如何做→分享发现→提醒保密→约定讨论时间→表达期待。考察疑问句和计划表达在书面语中的应用。

【能力项】
短消息写作｜邮件/便条，衔接与连贯｜连词使用""",
    "t2": ""
})

# ====================================================================
# 写作-P1-011701: Because it's..., We should talk to... right now., It tells the story of... a long time ago.
# ====================================================================
RECORDS.append({
    "table": "writing_email", "sid": "011701", "type": "写作-P1",
    "json": {
        "first": {
            "category": "writing",
            "type": "writing_email",
            "questionSetID": "011701",
            "textDesc": "Your friend Sam wants to know about a story you made. Write an email to tell him.<br>Put these sentences in order to make a complete description.",
            "optionSetList": [
                "Dear Sam,",
                "I'm so glad you asked about my story!",
                "Because it's about a brave little dragon named Spark.",
                "We should talk to the teacher right now about showing it to our class.",
                "It tells the story of Spark finding a lost treasure a long time ago.",
                "Looking forward to hearing from you! Best, Your Friend"
            ],
            "answerSet": [0, 1, 2, 3, 4, 5],
            "ability": ["短消息写作｜邮件/便条", "衔接与连贯｜连词使用"],
            "explanation": "按照邮件和叙述逻辑：问候→表达高兴→说明原因→提议后续行动→补充故事内容→结尾。考察because引导的原因句和故事背景描述能力。"
        },
        "second": {}
    },
    "t1": """【题目描述】
Your friend Sam wants to know about a story you made. Write an email to tell him.
Put these sentences in order to make a complete description.

【段落列表】
A. Dear Sam,
B. I'm so glad you asked about my story!
C. Because it's about a brave little dragon named Spark.
D. We should talk to the teacher right now about showing it to our class.
E. It tells the story of Spark finding a lost treasure a long time ago.
F. Looking forward to hearing from you! Best, Your Friend

【答案】
A, B, C, D, E, F

【解析】
按照邮件和叙述逻辑：问候→表达高兴→说明原因→提议后续行动→补充故事内容→结尾。考察because引导的原因句和故事背景描述能力。

【能力项】
短消息写作｜邮件/便条，衔接与连贯｜连词使用""",
    "t2": ""
})

# ====================================================================
# 口语-P1-011301: He looks like..., You are so..., I am good at...
# ====================================================================
RECORDS.append({
    "table": "speaking_qa", "sid": "011301", "type": "口语-P1",
    "json": {
        "first": {
            "category": "speaking",
            "type": "speaking_qa",
            "asrPrompt": "best,friend,look,like,tall,kind,good,at,drawing,running",
            "questionSetID": "011301",
            "textDesc": "Answer these questions about your friends and yourself. Use full English sentences.",
            "questionSet": [
                {
                    "content": "What does your best friend look like?",
                    "ability": ["基础信息表达｜个人信息问答"],
                    "explanation": "你可以用"He looks like..."或"She looks like..."来描述朋友的外貌特征，例如 tall、short、funny 等。试着说出2-3个特征，让描述更完整。"
                },
                {
                    "content": "How would you describe your dad or mom?",
                    "ability": ["表达喜好与理由"],
                    "explanation": "你可以用"You are so..."来表达对家人的描述和感受，例如 kind、strong、helpful 等。用完整的句子加上一个简单的理由会更好。"
                },
                {
                    "content": "What are you good at doing?",
                    "ability": ["基础信息表达｜个人信息问答"],
                    "explanation": "你可以用"I am good at..."来回答，然后说出你擅长的具体事情，例如 drawing、running 或 playing football。试着用 because 加一句解释。"
                },
                {
                    "content": "Who is good at helping you at home?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以回答家人擅长的家务，例如"My dad is good at cooking"或"My mom is good at..."，用完整句子描述具体帮助你的方式。"
                }
            ]
        },
        "second": {}
    },
    "t1": """【题目描述】
Answer these questions about your friends and yourself. Use full English sentences.

【题目】
1. What does your best friend look like?
2. How would you describe your dad or mom?
3. What are you good at doing?
4. Who is good at helping you at home?""",
    "t2": ""
})

# ====================================================================
# 口语-P1-011401: We should ask... about..., Let's/Let me..., Don't... in...
# ====================================================================
RECORDS.append({
    "table": "speaking_qa", "sid": "011401", "type": "口语-P1",
    "json": {
        "first": {
            "category": "speaking",
            "type": "speaking_qa",
            "asrPrompt": "ask,teacher,school,trip,help,friend,library,run,rules",
            "questionSetID": "011401",
            "textDesc": "Answer these questions. Think about how to ask for help, offer help, or give rules in English.",
            "questionSet": [
                {
                    "content": "If you want to know about the school trip, what will you say to your teacher?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以用"We should ask our teacher about..."来提出建议。例如"We should ask our teacher about the school trip time." 这个句型适合用于礼貌地提出询问。"
                },
                {
                    "content": "If you see your friend carrying heavy books, what will you say?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以用"Let me..."来主动提供帮助，例如"Let me help you with those books." 这个句型展示了友善和主动帮忙的态度。"
                },
                {
                    "content": "If you see someone running in the library, what will you say to them?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以用"Don't... in the library." 来表达规则提醒，例如"Don't run in the library." 这是一个礼貌提醒他人遵守规则的好方式。"
                },
                {
                    "content": "If your dog is sick, who should you talk to?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你需要回答应该找谁帮忙，可以尝试用"We should ask..." 来造句。例如"We should ask the vet about our dog." 考察如何表达寻求合适帮助的能力。"
                }
            ]
        },
        "second": {}
    },
    "t1": """【题目描述】
Answer these questions. Think about how to ask for help, offer help, or give rules in English.

【题目】
1. If you want to know about the school trip, what will you say to your teacher?
2. If you see your friend carrying heavy books, what will you say?
3. If you see someone running in the library, what will you say to them?
4. If your dog is sick, who should you talk to?""",
    "t2": ""
})

# ====================================================================
# 口语-P1-011501: Let's wait and see..., Please give him..., He didn't mean to...
# ====================================================================
RECORDS.append({
    "table": "speaking_qa", "sid": "011501", "type": "口语-P1",
    "json": {
        "first": {
            "category": "speaking",
            "type": "speaking_qa",
            "asrPrompt": "wait,see,tomorrow,scores,brother,hungry,lunch,mom,broke,cup,accident",
            "questionSetID": "011501",
            "textDesc": "Answer these questions about everyday situations. Think about patience, asking nicely, and explaining accidents.",
            "questionSet": [
                {
                    "content": "Your friend wants to check the test scores, but the teacher says the scores come out tomorrow. What will you say to your friend?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以用"Let's wait and see..."来安慰朋友不要着急。例如"Let's wait and see the scores tomorrow." 这个句型展现出耐心和积极的态度。"
                },
                {
                    "content": "Your little brother is hungry, but he forgot his lunch at home. What will you ask your mom?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以用"Please give him..."来礼貌地请求妈妈帮忙。例如"Please give him some of my lunch." 或者"Please give him something to eat." 这是礼貌请求的好方式。"
                },
                {
                    "content": "Your friend broke a cup by accident. He feels very sorry. What will you tell your mom?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以用"He didn't mean to..."来解释这不是故意的。例如"He didn't mean to break the cup." 这是帮助别人解释无心之失的好表达。"
                },
                {
                    "content": "You want to see a film with your friend. Your friend says he is busy. What will you say?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "用"Let's wait and see..."来表达理解并建议改时间。例如"Let's wait and see if we can go next weekend." 展现出灵活和体贴的态度。"
                }
            ]
        },
        "second": {}
    },
    "t1": """【题目描述】
Answer these questions about everyday situations. Think about patience, asking nicely, and explaining accidents.

【题目】
1. Your friend wants to check the test scores, but the teacher says the scores come out tomorrow. What will you say to your friend?
2. Your little brother is hungry, but he forgot his lunch at home. What will you ask your mom?
3. Your friend broke a cup by accident. He feels very sorry. What will you tell your mom?
4. You want to see a film with your friend. Your friend says he is busy. What will you say?""",
    "t2": ""
})

# ====================================================================
# 口语-P1-011701: On my shopping list, there are... and..., I think we can go to the..., I think we're going to...
# ====================================================================
RECORDS.append({
    "table": "speaking_qa", "sid": "011701", "type": "口语-P1",
    "json": {
        "first": {
            "category": "speaking",
            "type": "speaking_qa",
            "asrPrompt": "shopping,list,milk,bread,eggs,supermarket,toy,shop,weekend,park,zoo",
            "questionSetID": "011701",
            "textDesc": "Answer these questions about shopping and weekend plans. Use full English sentences.",
            "questionSet": [
                {
                    "content": "What do you need to buy at the supermarket?",
                    "ability": ["基础信息表达｜个人信息问答"],
                    "explanation": "你可以用"On my shopping list, there are... and..."来列出你要买的物品。例如"On my shopping list, there are milk and eggs." 用这个句型你就能说出购物清单了。"
                },
                {
                    "content": "Where do you think you can buy a new toy?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以用\"I think we can go to the..."来表达你的建议。例如"I think we can go to the toy shop." 用I think来表达你的想法，这是很自然的英语表达。"
                },
                {
                    "content": "What do you think your family will do this weekend?",
                    "ability": ["基础信息表达｜个人信息问答"],
                    "explanation": "你可以用\"I think we're going to..."来猜测和表达周末计划。例如"I think we're going to the park." 或者"I think we're going to visit my grandparents." 这是一个表达未来计划的常用句型。"
                },
                {
                    "content": "If you could buy one special thing today, what would it be?",
                    "ability": ["表达喜好与理由"],
                    "explanation": "用完整句子描述你想买的特别物品和原因。例如"I think I would buy a new book because I love reading." 试着用because来解释你的选择。"
                }
            ]
        },
        "second": {}
    },
    "t1": """【题目描述】
Answer these questions about shopping and weekend plans. Use full English sentences.

【题目】
1. What do you need to buy at the supermarket?
2. Where do you think you can buy a new toy?
3. What do you think your family will do this weekend?
4. If you could buy one special thing today, what would it be?""",
    "t2": ""
})

# ====================================================================
# 写作-P2-011601: What time does the... start?, Why must we...?, It was caused by...
# ====================================================================
RECORDS.append({
    "table": "writing_picWrite", "sid": "011601", "type": "写作-P2",
    "json": {
        "first": {
            "category": "writing",
            "type": "writing_picWrite",
            "questionSetID": "011601",
            "textImage": "011601-00.png",
            "textDesc": "Look at the three pictures. They tell a story about a school sports day. Put these sentences in order to tell the story.",
            "optionSetList": [
                "Tom asked, \"What time does the sports day start?\" His teacher told him it would start at 9 o'clock.",
                "Everyone was excited. But soon, the sky got very dark. It was caused by a big rain cloud coming in.",
                "Just as the race was about to start, it began to rain hard! Why must we stop? Tom was very sad.",
                "The head teacher said, \"Don't worry! Let's move the races to the big hall inside.\"",
                "Everyone ran to the hall. Tom won the first race and everyone cheered!",
                "After the sports day, Tom's mom said it was the best day ever, even with the rain!"
            ],
            "answerSet": [0, 1, 2, 3, 4, 5],
            "ability": ["叙述故事｜看图写故事", "衔接与连贯｜连词使用"],
            "explanation": "根据三张图片的时间顺序排列句子：询问开始时间→天空变暗→下雨停止比赛→转移场地→比赛继续→总结美好一天。考察叙事逻辑和事件衔接能力。"
        },
        "second": {}
    },
    "t1": """【题目描述】
Look at the three pictures. They tell a story about a school sports day. Put these sentences in order to tell the story.

【段落列表】
A. Tom asked, "What time does the sports day start?" His teacher told him it would start at 9 o'clock.
B. Everyone was excited. But soon, the sky got very dark. It was caused by a big rain cloud coming in.
C. Just as the race was about to start, it began to rain hard! Why must we stop? Tom was very sad.
D. The head teacher said, "Don't worry! Let's move the races to the big hall inside."
E. Everyone ran to the hall. Tom won the first race and everyone cheered!
F. After the sports day, Tom's mom said it was the best day ever, even with the rain!

【答案】
A, B, C, D, E, F

【解析】
根据三张图片的时间顺序排列句子：询问开始时间→天空变暗→下雨停止比赛→转移场地→比赛继续→总结美好一天。考察叙事逻辑和事件衔接能力。

【能力项】
叙述故事｜看图写故事，衔接与连贯｜连词使用""",
    "t2": ""
})

# ====================================================================
# 口语-P2-011601: Where did you last see...?, Be careful, or you might..., There is a... and a... nearby.
# ====================================================================
RECORDS.append({
    "table": "speaking_topic", "sid": "011601", "type": "口语-P2",
    "json": {
        "first": {
            "category": "speaking",
            "type": "speaking_topic",
            "asrPrompt": "park,community,lost,found,careful,slide,swing,bench,shop,cafe",
            "questionSetID": "011601",
            "textDesc": "Look at the picture of a community park. Talk about what you see. Think about safety and what is around you.",
            "imageDesc": "A community park scene with children playing. There is a playground with a slide and swings. A small shop and a cafe are nearby. A child is looking for something he lost. A parent is reminding another child to be careful near the playground equipment.",
            "textImage": "011601-00.png",
            "questionSet": [
                {
                    "content": "Where did you last see your toy in the park?",
                    "ability": ["故事讲述｜看图说话"],
                    "explanation": "你可以用"Where did you last see..."来说出你最后在哪里见过某物。例如"I last saw my toy near the slide." 具体描述位置信息能让回答更完整。"
                },
                {
                    "content": "What should you say to your little brother if he climbs too high on the slide?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "你可以用"Be careful, or you might..."来善意提醒他人。例如"Be careful, or you might fall." 这是一个既表达关心又能给出安全提醒的好句子。"
                },
                {
                    "content": "What places are near the park?",
                    "ability": ["故事讲述｜看图说话"],
                    "explanation": "你可以用"There is a... and a... nearby."来描述附近的设施。例如"There is a shop and a cafe nearby." 这个句型能帮你清楚地描述周边环境。"
                },
                {
                    "content": "What should you do if you lose something in the park?",
                    "ability": ["互动应答｜问答交流"],
                    "explanation": "试着用完整句子描述你会怎么做。例如"First I would look around the playground, then I would ask my parents for help." 用first和then来组织语言会更有条理。"
                }
            ]
        },
        "second": {}
    },
    "t1": """【题目描述】
Look at the picture of a community park. Talk about what you see. Think about safety and what is around you.

【题目】
1. Where did you last see your toy in the park?
2. What should you say to your little brother if he climbs too high on the slide?
3. What places are near the park?
4. What should you do if you lose something in the park?""",
    "t2": ""
})

# ====================================================================
# BACKFILL
# ====================================================================
print(f"Generated {len(RECORDS)} records")

# Get token
with open(CRED_FILE) as f:
    cfg = json.load(f)
req = urllib.request.Request(
    "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
    data=json.dumps({"app_id": cfg['apps'][0]['appId'], "app_secret": cfg['apps'][0]['appSecret']}).encode(),
    headers={"Content-Type": "application/json"})
token = json.loads(urllib.request.urlopen(req).read())['tenant_access_token']

def api_call(url, method='GET', body=None):
    headers = {"Authorization": f"Bearer {token}"}
    data = json.dumps(body).encode() if body else None
    if data:
        headers["Content-Type"] = "application/json"
    req = urllib.request.Request(url, data=data, method=method, headers=headers)
    return json.loads(urllib.request.urlopen(req).read())

# For each record, find if exists in bitable, update or create
for rec in RECORDS:
    table_id = TABLES[rec['table']]
    sid = rec['sid']
    
    # List records to find matching ID
    url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records?page_size=100"
    resp = api_call(url)
    
    existing_rid = None
    for item in resp['data']['items']:
        if item['fields'].get('题目集合 ID', '') == sid:
            existing_rid = item['record_id']
            break
    
    new_jd = json.dumps(rec['json'], ensure_ascii=False)
    fields = {
        "题目集合 ID": sid,
        "jsonData": new_jd
    }
    
    # Add 题目1 field
    t1_key = next((k for k in item['fields'] if k in ['题目1']), '题目1') if existing_rid else '题目1'
    if rec.get('t1'):
        fields[t1_key] = rec['t1']
    
    # Try to add 题目2 if table supports it
    if rec.get('t2'):
        # Check if field exists
        if existing_rid:
            for k in item['fields']:
                if '题目2' in k:
                    fields[k] = rec['t2']
                    break
    
    if existing_rid:
        result = api_call(
            f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/{existing_rid}",
            'PUT', {"fields": fields}
        )
        status = "UPD" if result.get('code') == 0 else f"ERR:{result.get('msg')}"
    else:
        result = api_call(
            f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records",
            'POST', {"fields": fields}
        )
        status = "NEW" if result.get('code') == 0 else f"ERR:{result.get('msg')}"
    
    print(f"  {status} {rec['type']} {sid}: {rec['table']}")
    if result.get('code') != 0:
        print(f"    ERROR: {result.get('msg')}")

print(f"\n✅ All {len(RECORDS)} records processed!")
