#!/usr/bin/env python3
"""reading_matchInfo 021301-021801 (6套), L2 B级 3-5词短句通知"""
import json, requests, time

CRED = "/root/.openclaw/credentials/xiaoyan/config.json"
TOKEN_APP = "CMHSbUUjka3TrUsaxxEc297ongf"
TBL = "tblCgfYDnnqwLfgH"
AB = ["标识与通知理解｜标识 & 通知"]

with open(CRED) as f:
    cred = json.load(f)
aid = cred["apps"][0]["appId"]
asecret = cred["apps"][0]["appSecret"]

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

# ==================== QUESTION DATA ====================
# Each entry: (questionImage, question, [options], [answer_index], explanation)
# Format: image text is 3-5 word real notice/sign

I = lambda img, q, opts, ans, exp: {
    "questionImage": img, "question": q, "options": opts,
    "answer": ans, "explanation": exp
}

DATA = {
    "021301": {
        "first": [
            I("021301-00.png","What does this poster say?",
              ["The singer is here","The actor is on stage","The dancer is late"],[1],
              "海报上写着 The ACTOR is on stage，演员在舞台上。"),
            I("021301-01.png","What does the man have?",
              ["White hair","Black beard","Red hat"],[1],
              "通缉令上写着 Man with black BEARD，男子有黑胡子。"),
            I("021301-02.png","What does the label say?",
              ["The pictures are the same","The pictures are different","The pictures are old"],[1],
              "标签上写着 These pictures are DIFFERENT，两幅画不一样。"),
            I("021301-03.png","What was Lily today?",
              ["Brave","Sad","Tired"],[0],
              "奖状上写着 Lily was very BRAVE today，Lily 今天很勇敢。"),
            I("021301-04.png","Who just moved in?",
              ["A new teacher","A new neighbour","A new student"],[1],
              "卡片上写着 A new NEIGHBOUR moved in，新邻居搬来了。"),
        ],
        "second": [
            I("021301-05.png","What time is dinner?",
              ["At five","At six","At seven"],[1],
              "便条上写着 DINNER at six tonight，晚饭六点吃。"),
            I("021301-06.png","What is Mum doing?",
              ["Sleeping","Cooking","Reading"],[1],
              "门牌上写着 Mum is COOKING right now，妈妈在做饭。"),
            I("021301-07.png","What kind of exit is this?",
              ["Fire exit","Park exit","Shop exit"],[0],
              "标志上写着 FIRE exit this way，这是消防出口。"),
            I("021301-08.png","What is on show Friday?",
              ["A family album","A film","A play"],[0],
              "海报上写着 Family ALBUM on show Friday，周五展示家庭相册。"),
            I("021301-09.png","What does this note ask?",
              ["Read my diary","Do not read my diary","Buy a new diary"],[1],
              "便条上写着 Do not read my DIARY，不要看我的日记。"),
        ],
        "desc": """1.
图片材料文本：
The ACTOR is on stage.

图片材料文本：
Man with black BEARD wanted.

图片材料文本：
These pictures are DIFFERENT.

图片材料文本：
Lily was very BRAVE today.

图片材料文本：
A new NEIGHBOUR moved in.

2.
图片材料文本：
DINNER at six tonight.

图片材料文本：
Mum is COOKING right now.

图片材料文本：
FIRE exit this way →

图片材料文本：
Family ALBUM on show Friday.

图片材料文本：
Do not read my DIARY.""",
    },
    "021401": {
        "first": [
            I("021401-00.png","What should you plan?",
              ["Your weekend","Your lesson","Your dinner"],[0],
              "便签上写着 PLAN your weekend now，现在就计划周末吧。"),
            I("021401-01.png","How fast is the bike repair?",
              ["In one day","In one hour","In one week"],[1],
              "店招牌上写着 Bike REPAIR in one hour，一小时修好自行车。"),
            I("021401-02.png","Where is today's newspaper?",
              ["On the shelf","On the desk","In the bag"],[1],
              "图书馆标牌上写着 Today's NEWSPAPER on the desk，报纸在桌上。"),
            I("021401-03.png","What is lost?",
              ["A blue backpack","A red pen","A white book"],[0],
              "失物招领上写着 Lost: Blue BACKPACK in Room 3，蓝色背包丢了。"),
            I("021401-04.png","What should you do on the bus?",
              ["Stand up","Give your seat to old people","Sing songs"],[1],
              "公交标牌上写着 Give your SEAT to old people，给老人让座。"),
        ],
        "second": [
            I("021401-05.png","When is the garden open?",
              ["In the morning","After class","At lunch"],[1],
              "公告上写着 School GARDEN open after class，花园放学后开放。"),
            I("021401-06.png","What fruit is on sale?",
              ["Apple","Banana","Melon"],[2],
              "市场标牌上写着 Sweet MELON for sale today，今天甜瓜热卖。"),
            I("021401-07.png","What does this lake sign say?",
              ["Drink lake water","Do not drink lake water","Swim in the lake"],[1],
              "警示牌上写着 Do not drink lake WATER，不要喝湖水。"),
            I("021401-08.png","When should you plant a tree?",
              ["On Monday","On Friday","On Sunday"],[1],
              "公告上写着 PLANT a tree on Friday，周五植树。"),
            I("021401-09.png","What starts next week?",
              ["Summer camp","Winter camp","Spring class"],[0],
              "校园通知上写着 SUMMER camp starts next week，夏令营下周开始。"),
        ],
        "desc": """1.
图片材料文本：
PLAN your weekend now.

图片材料文本：
Bike REPAIR in one hour.

图片材料文本：
Today's NEWSPAPER on the desk.

图片材料文本：
Lost: Blue BACKPACK in Room 3.

图片材料文本：
Give your SEAT to old people.

2.
图片材料文本：
School GARDEN open after class.

图片材料文本：
Sweet MELON for sale today.

图片材料文本：
Do not drink lake WATER.

图片材料文本：
PLANT a tree on Friday.

图片材料文本：
SUMMER camp starts next week.""",
    },
    "021501": {
        "first": [
            I("021501-00.png","Where should visitors sign in?",
              ["At the gate","At the office","At the shop"],[1],
              "校门标识上写着 VISITORs sign in at the office，访客去办公室签到。"),
            I("021501-01.png","What kind of party is it?",
              ["Birthday party","School party","Garden party"],[0],
              "横幅上写着 WELCOME to the birthday party，生日派对欢迎你。"),
            I("021501-02.png","Whose party are you invited to?",
              ["Lily's","Tom's","Mum's"],[1],
              "邀请函上写着 You are INVITEd to Tom's party，你被邀请参加Tom的派对。"),
            I("021501-03.png","What can you do here?",
              ["Sleep","Laugh","Cry"],[1],
              "海报上写着 Come and LAUGH with us，来和我们一起大笑。"),
            I("021501-04.png","What time does breakfast end?",
              ["At 7 a.m.","At 8 a.m.","At 9 a.m."],[2],
              "酒店通知上写着 GUESTs: breakfast 7 to 9 a.m.，早餐9点结束。"),
        ],
        "second": [
            I("021501-05.png","What should you check for?",
              ["Mistakes","Stars","Pictures"],[0],
              "作业提醒上写着 Check for MISTAKEs first，先检查有没有错误。"),
            I("021501-06.png","What should you read carefully?",
              ["The story","The instruction","The picture"],[1],
              "考试通知上写着 Read the INSTRUCTION carefully，仔细读说明。"),
            I("021501-07.png","What must you give if late?",
              ["A reason","A gift","A book"],[0],
              "办公室告知上写着 Give a REASON if late，迟到要说明原因。"),
            I("021501-08.png","Where must you not bring drinks?",
              ["Near the library","Near technology room","Near the garden"],[1],
              "电脑室标识上写着 No drinks near TECHNOLOGY room，科技室附近不准带饮料。"),
            I("021501-09.png","Where should you wash your brush?",
              ["At home","Here","Outside"],[1],
              "美术室标识上写着 Wash your paint BRUSH here，在这里洗画笔。"),
        ],
        "desc": """1.
图片材料文本：
VISITORs sign in at the office.

图片材料文本：
WELCOME to the birthday party!

图片材料文本：
You are INVITEd to Tom's party.

图片材料文本：
Come and LAUGH with us!

图片材料文本：
GUESTs: breakfast 7 to 9 a.m.

2.
图片材料文本：
Check for MISTAKEs first.

图片材料文本：
Read the INSTRUCTION carefully.

图片材料文本：
Give a REASON if late.

图片材料文本：
No drinks near TECHNOLOGY room.

图片材料文本：
Wash your paint BRUSH here.""",
    },
    "021601": {
        "first": [
            I("021601-00.png","What is the new record in?",
              ["Run","Jump","Swim"],[1],
              "体育公告上写着 New school RECORD in jump，跳高破了新纪录。"),
            I("021601-01.png","What is the big event?",
              ["Sports day","Exam day","Book day"],[0],
              "公告上写着 Sports day — a big EVENT，运动会是件大事。"),
            I("021601-02.png","Who must you have to enter?",
              ["A friend","A teacher","A parent"],[1],
              "门上写着 Do not ENTER without teacher，没有老师不能进。"),
            I("021601-03.png","When should you return books?",
              ["By Monday","By Friday","By Sunday"],[1],
              "图书馆通知上写着 RETURN books by this Friday，周五前还书。"),
            I("021601-04.png","What should you sort?",
              ["Paper and food","Paper and glass","Glass and water"],[1],
              "回收标识上写着 Please SORT paper and glass，请把纸和玻璃分开。"),
        ],
        "second": [
            I("021601-05.png","What colour is the handbag?",
              ["Blue","Red","Green"],[1],
              "失物招领上写着 Lost: red HANDBAG near playground，丢了红色手提包。"),
            I("021601-06.png","What is not allowed here?",
              ["Camera","Books","Shoes"],[0],
              "展馆标识上写着 No CAMERA in this room，此房间不许拍照。"),
            I("021601-07.png","When does the park gate close?",
              ["At seven","At eight","At nine"],[1],
              "公园标牌上写着 Park GATE closes at eight，大门8点关闭。"),
            I("021601-08.png","How long to fix a wheel?",
              ["10 minutes","30 minutes","60 minutes"],[1],
              "车店标牌上写着 Fix your WHEEL in 30 minutes，30分钟修好轮子。"),
            I("021601-09.png","Where is the main entrance?",
              ["South side","East side","North side"],[2],
              "大楼标识上写着 Main ENTRANCE on north side，主入口在北边。"),
        ],
        "desc": """1.
图片材料文本：
New school RECORD in jump!

图片材料文本：
Sports day — a big EVENT.

图片材料文本：
Do not ENTER without teacher.

图片材料文本：
RETURN books by this Friday.

图片材料文本：
Please SORT paper and glass.

2.
图片材料文本：
Lost: red HANDBAG near playground.

图片材料文本：
No CAMERA in this room.

图片材料文本：
Park GATE closes at eight.

图片材料文本：
Fix your WHEEL in 30 minutes.

图片材料文本：
Main ENTRANCE on north side.""",
    },
    "021701": {
        "first": [
            I("021701-00.png","Who should you not talk to?",
              ["The driver","The guard","The teacher"],[0],
              "公交标牌上写着 Do not talk to the DRIVER，不要和司机说话。"),
            I("021701-01.png","Where should you look both ways?",
              ["At school","On the street","At home"],[1],
              "安全海报上写着 Look both ways on the STREET，过街道要左右看。"),
            I("021701-02.png","When is the farmers' market?",
              ["Every Monday","Every Saturday","Every Sunday"],[1],
              "市场标牌上写着 Farmers' MARKET every Saturday，每周六有农夫市集。"),
            I("021701-03.png","Where can you get a guidebook?",
              ["At this desk","At the gate","In the shop"],[0],
              "咨询台标牌上写着 Free GUIDEBOOK at this desk，此处免费领指南。"),
            I("021701-04.png","What time does shopping start?",
              ["At 10 a.m.","At 11 a.m.","At 12 p.m."],[0],
              "商场标牌上写着 SHOPPING hours: 10 a.m. to 8 p.m.，购物10点开始。"),
        ],
        "second": [
            I("021701-05.png","Where is the washing machine?",
              ["On first floor","On second floor","Outside"],[0],
              "洗衣房标识上写着 Washing MACHINE on first floor，洗衣机在一楼。"),
            I("021701-06.png","What should you draw?",
              ["Your school","Your family","Your pet"],[1],
              "美术社通知上写着 DRAW your family for the show，画你的家人参展。"),
            I("021701-07.png","When is basketball practice?",
              ["At three","At four","At five"],[1],
              "体育通知上写着 BASKETBALL practice at four today，今天四点篮球训练。"),
            I("021701-08.png","Where should you put the books?",
              ["On the desk","On the bookcase","On the floor"],[1],
              "图书馆标识上写着 Put books on the BOOKCASE，把书放回书柜。"),
            I("021701-09.png","When is the science fair?",
              ["On Friday","On Monday","On Wednesday"],[1],
              "科学展标识上写着 Show your INVENTION on Monday，周一展示你的发明。"),
        ],
        "desc": """1.
图片材料文本：
Do not talk to the DRIVER.

图片材料文本：
Look both ways on the STREET.

图片材料文本：
Farmers' MARKET every Saturday.

图片材料文本：
Free GUIDEBOOK at this desk.

图片材料文本：
SHOPPING hours: 10 a.m. to 8 p.m.

2.
图片材料文本：
Washing MACHINE on first floor.

图片材料文本：
DRAW your family for the show.

图片材料文本：
BASKETBALL practice at four today.

图片材料文本：
Put books on the BOOKCASE.

图片材料文本：
Show your INVENTION on Monday.""",
    },
    "021801": {
        "first": [
            I("021801-00.png","What time does the library close?",
              ["At 2 p.m.","At 4 p.m.","At 6 p.m."],[1],
              "图书馆通知上写着 LIBRARY open 8 a.m. to 4 p.m.，下午4点闭馆。"),
            I("021801-01.png","Where can you read the magazines?",
              ["At home","Here only","In the park"],[1],
              "阅览室标牌上写着 New MAGAZINEs — read here only，杂志仅供此处阅读。"),
            I("021801-02.png","What is on at three?",
              ["A film","A cartoon","A play"],[1],
              "TV室标牌上写着 CARTOON at three this afternoon，下午三点播动画片。"),
            I("021801-03.png","When is the English test?",
              ["Friday morning","Monday afternoon","Wednesday evening"],[0],
              "考试通知上写着 English TEST on Friday morning，周五上午英语考试。"),
            I("021801-04.png","How should you read the instructions?",
              ["Quickly","Carefully","Slowly"],[1],
              "实验室标牌上写着 Read CAREFULLY before you start，开始前仔细阅读。"),
        ],
        "second": [
            I("021801-05.png","What does the toy need?",
              ["A new book","A new battery","A new bag"],[1],
              "玩具上贴着 This toy needs a new BATTERY，玩具需要新电池。"),
            I("021801-06.png","Where is the reading corner?",
              ["On the right","On the left","In the middle"],[1],
              "图书馆标牌上写着 Reading CORNER on the left side，阅读角在左边。"),
            I("021801-07.png","When is the school play?",
              ["On Friday","On Saturday","On Sunday"],[1],
              "校公告上写着 Play at the THEATRE this Saturday，周六剧院有演出。"),
            I("021801-08.png","What should you not climb?",
              ["The wall","The stairs","The park trees"],[2],
              "公园警示牌上写着 Do not CLIMB the park trees，不要爬公园的树。"),
            I("021801-09.png","When is lunch today?",
              ["At midday","At one","At two"],[0],
              "食堂通知上写着 Lunch is at MIDDAY today，今天中午十二点午饭。"),
        ],
        "desc": """1.
图片材料文本：
LIBRARY open 8 a.m. to 4 p.m.

图片材料文本：
New MAGAZINEs — read here only.

图片材料文本：
CARTOON at three this afternoon.

图片材料文本：
English TEST on Friday morning.

图片材料文本：
Read CAREFULLY before you start.

2.
图片材料文本：
This toy needs a new BATTERY.

图片材料文本：
Reading CORNER on the left side.

图片材料文本：
Play at the THEATRE this Saturday.

图片材料文本：
Do not CLIMB the park trees.

图片材料文本：
Lunch is at MIDDAY today.""",
    },
}

# ==================== BUILD & WRITE ====================
def build(qid):
    def qset(qs):
        return [{
            "questionImage": q["questionImage"], "question": q["question"],
            "options": q["options"], "answer": q["answer"],
            "ability": AB, "explanation": q["explanation"],
        } for q in qs]
    return {
        "first": {"category": "reading", "type": "reading_matchInfo", "questionSetID": qid, "questionSet": qset(DATA[qid]["first"])},
        "second": {"category": "reading", "type": "reading_matchInfo", "questionSetID": qid, "questionSet": qset(DATA[qid]["second"])},
    }

# === STEP 1: Create empty records ===
token = get_token()
print("=== Step 1: Create empty records ===")
new_rids = {}
for qid in sorted(DATA):
    r = requests.post(
        f"https://open.feishu.cn/open-apis/bitable/v1/apps/{TOKEN_APP}/tables/{TBL}/records",
        headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
        json={"fields": {"题目集合 ID": qid, "dataStatus": "0"}})
    new_rids[qid] = r.json()["data"]["record"]["record_id"]
    print(f"  {qid}: {new_rids[qid]}")
    time.sleep(0.5)

# === STEP 2: Wait for automation ===
print("\n=== Step 2: Wait 35s ===")
time.sleep(35)

# === STEP 3: PUT jsonData ===
print("\n=== Step 3: PUT jsonData ===")
token = get_token()
for qid in sorted(new_rids):
    j = build(qid)
    js = json.dumps(j, ensure_ascii=False)
    r = requests.put(
        f"https://open.feishu.cn/open-apis/bitable/v1/apps/{TOKEN_APP}/tables/{TBL}/records/{new_rids[qid]}",
        headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
        json={"fields": {"jsonData": js}})
    print(f"  {qid}: json={len(js)}chars code={r.json().get('code')}")
    time.sleep(0.5)

# === STEP 4: Wait then PUT 图片描述 ===
print("\n=== Step 4: Wait 15s + PUT 图片描述 ===")
time.sleep(15)
token = get_token()
for qid in sorted(new_rids):
    r = requests.put(
        f"https://open.feishu.cn/open-apis/bitable/v1/apps/{TOKEN_APP}/tables/{TBL}/records/{new_rids[qid]}",
        headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
        json={"fields": {"图片描述": DATA[qid]["desc"]}})
    print(f"  {qid}: desc code={r.json().get('code')} len={len(DATA[qid]['desc'])}")
    time.sleep(0.5)

# === STEP 5: Final verify ===
print("\n=== Step 5: Wait 20s + Verify ===")
time.sleep(20)
token = get_token()
for qid in sorted(new_rids):
    r = requests.get(
        f"https://open.feishu.cn/open-apis/bitable/v1/apps/{TOKEN_APP}/tables/{TBL}/records/{new_rids[qid]}",
        headers={"Authorization": f"Bearer {token}"})
    fields = r.json()["data"]["record"]["fields"]
    jd = fields.get("jsonData", "")
    desc = fields.get("图片描述", "") or ""
    try:
        j = json.loads(jd)
        fq = len(j["first"]["questionSet"])
        sq = len(j["second"]["questionSet"])
        ok = (fq == 5 and sq == 5 and len(desc) > 100)
        print(f"  {'✅' if ok else '❌'} {qid} ({new_rids[qid]}): {fq}/{sq}q desc={len(desc)}chars")
    except Exception as e:
        print(f"  ❌ {qid}: {e}")

print("\nDone.")
