"""Verify remote commit, native Yunxiao associations, effort records and QA handoff."""
import datetime
import html
import json
import subprocess
import sys
from pathlib import Path
HERE=Path(__file__).resolve().parent
ROOT=HERE.parents[1]
REPO=ROOT.parent/'zhctproject/store'
sys.path.insert(0,str(ROOT/'work_store/VWCG-1450-consume-order-department-bulk-select/yunxiao'))
from transport import api,PREFIX,ORG,compact
items=json.loads((HERE/'items.sanitized.json').read_text())
OWNER='635755195dc8531eeb2e33d9'
STATE=HERE/'delivery.sanitized.json'
state=json.loads(STATE.read_text()) if STATE.exists() else {'items':{}}
def save(): STATE.write_text(json.dumps(state,ensure_ascii=False,indent=2)+'\n')
def rows(v): return v if isinstance(v,list) else (v or {}).get('result',(v or {}).get('items',[]))
def git(*a): return subprocess.check_output(['git','-C',str(REPO),*a],text=True).strip()
def relations(item_id):
    errors=[]
    for pre in [PREFIX+'/workitems/','/oapi/v1/projex/workitems/']:
        try: return pre,rows(api('GET',pre+item_id+'/extRelationRecords?category=codeupCommit'))
        except RuntimeError as e: errors.append(str(e))
    raise RuntimeError('; '.join(errors))
def rich(text):
    return ''.join('<h2>'+html.escape(s[3:])+'</h2>' if s.startswith('## ') else '<p>'+html.escape(s)+'</p>' for s in text.splitlines() if s)
assert git('branch','--show-current')=='guoxin_develop'
sha=git('rev-parse','HEAD');subject=git('show','-s','--format=%s',sha)
assert subject.startswith('#'+items['tasks']['development']['serialNumber']+' ')
remote=git('ls-remote','--heads','origin','refs/heads/guoxin_develop').split()[0];assert sha==remote
repo=api('GET',f'/oapi/v1/codeup/organizations/{ORG}/repositories/4913137')
assert repo['pathWithNamespace']==ORG+'/zhct/store'
commit=api('GET',f'/oapi/v1/codeup/organizations/{ORG}/repositories/4913137/commits/{sha}')
assert commit.get('id',commit.get('sha'))==sha
url=repo['webUrl']+'/commit/'+sha
state.update({'branch':'guoxin_develop','commit':sha,'subject':subject,'commitUrl':url,'remoteHead':remote,'repositoryId':4913137,'mrCreated':False})
save()
for key,item,target,document in [
    ('parent',items['parent'],'1dec9023be7be6cf79e6bde901','parent-use-case.md'),
    ('development',items['tasks']['development'],'100011','development-task.md'),
    ('validation',items['tasks']['validation'],'100010','validation-task.md'),
]:
    current=api('GET',PREFIX+'/workitems/'+item['id']);assert current['assignedTo']['id']==OWNER
    wf=api('GET',PREFIX+'/workitems/'+item['id']+'/workflow');assert any(s['id']==target for s in wf['statuses'])
    assert current['status']['id'] in ['100005','100010','142838',target], 'Refuse to rewind advanced state'
    pre,existing=relations(item['id'])
    if not any(r.get('businessId',r.get('commitSha'))==sha and str(r.get('projectId'))=='4913137' for r in existing):
        api('POST',pre+item['id']+'/extRelationRecords',{'category':'codeupCommit','projectId':'4913137','commitSha':sha,'title':subject,'url':url})
    _,linked=relations(item['id']);assert any(r.get('businessId',r.get('commitSha'))==sha and str(r.get('projectId'))=='4913137' for r in linked)
    text=(HERE/document).read_text()+('\n## 已交付代码与验证\n- '+sha+'\n- '+url+
        '\n- origin/guoxin_develop与本地一致，不切分支、不新建跨分支MR、未部署。'
        '\n- 最终前端15套69项、国信161项2023断言、Node14生产构建通过；全仓507项2995断言26项既有失败ID不变。'
        '\n- 75项授权开发库真实服务落库和实际查询/导出回读已通过；真实页面分段选项默认现金、无原辅助说明。'
        '\n- 计划2026-10-19开始/完成，开发非AI预计4h、测试非AI预计2h；实际仅登记可核验时间窗口，不估填其他时段。'
        '\n- 待QA：PC表单HTTP完整提交、实际队列调度、部署加载和现场设备/第三方实网验证；不将局部通过代替全部现场验收。\n')
    api('PUT',PREFIX+'/workitems/'+item['id'],{'description':rich(text),'formatType':'RICHTEXT','status':target})
    result=api('GET',PREFIX+'/workitems/'+item['id']);assert result['status']['id']==target
    for marker in ['Use Case','UC-SUBSIDY-026','主流程','异常/恢复','验收标准','测试矩阵','DoR',sha]: assert marker in result['description']
    marker='VWCG1462-DELIVERY-'+sha[:9];comments=PREFIX+'/workitems/'+item['id']+'/comments'
    if not any(marker in str(c.get('content','')) for c in rows(api('GET',comments))):
        api('POST',comments,{'content':marker+'\n'+subject+'\n'+url+'\n原生关联真实commit已回读，非仅评论链接。UC-SUBSIDY-026 v1.3，DoR READY；手动现金可选单位、导入/规则固定单位，仅补贴批次标记，不改资金链路。UI已删除说明、使用等宽分段选项；前端69项/国信161项/Node14构建及开发库75项通过。全量26既有失败无新增。计划10月19日，开发预计4h、测试预计2h，实际只记已核验窗口；父待测试/开发完成/验收处理中。不新建跨分支MR、未部署。'})
    assert any(marker in str(c.get('content','')) for c in rows(api('GET',comments)))
    state['items'][key]={**compact(result),'commitRelationConfirmed':True,'commentReadbackConfirmed':True};save()
    print(result['serialNumber'],result['status']['name'],'native code link verified',flush=True)

for key,actual,start,end,marker,label in [
    ('development',0.4,'2026-10-19T14:43:39+08:00','2026-10-19T15:07:06.257+08:00','VWCG1462-OBSERVED-IMPLEMENTATION','已核验初始分析实现自测审查窗口'),
    ('validation',0.1,'2026-10-19T15:18:32+08:00','2026-10-19T15:27:18+08:00','VWCG1462-OBSERVED-LIVE-VALIDATION','已核验真实开发库备份测试与导出复核窗口'),
]:
    task=items['tasks'][key];path=PREFIX+'/workitems/'+task['id']+'/effortRecords'
    matches=[r for r in rows(api('GET',path)) if marker in str(r.get('description',''))];assert len(matches)<=1
    if not matches:
        api('POST',path,{'operatorId':OWNER,'actualTime':actual,
            'gmtStart':int(datetime.datetime.fromisoformat(start).timestamp()*1000),
            'gmtEnd':int(datetime.datetime.fromisoformat(end).timestamp()*1000),
            'description':marker+' '+label+'；按实际时间戳，以0.1小时取整登记。不累计并行代理；不包含未计时前期方案、后续界面优化及本次云效提交时间，未计部分不估填。'})
    records=rows(api('GET',path));matching=[r for r in records if marker in str(r.get('description',''))]
    assert len(matching)==1 and float(matching[0]['actualTime'])==actual
    assert matching[0]['owner']['id']==OWNER
    state.setdefault('effortRecords',{})[key]={k:matching[0].get(k) for k in ['id','actualTime','gmtStart','gmtEnd','description','owner']}
    full=api('GET',PREFIX+'/workitems/'+task['id'])
    fields={f['fieldId']:f['values'][0]['identifier'] for f in full['customFieldValues'] if f.get('values')}
    assert fields['79'].startswith('2026-10-19') and fields['80'].startswith('2026-10-19')
    assert float(fields['101586'])==items['tasks'][key]['estimatedHours']
    assert float(fields['101587'])>=actual
    state['items'][key]['actualHoursReadback']=float(fields['101587']);save()
state['allThreeReadbackConfirmed']=True;save()
print(json.dumps({'commit':sha,'actualRegisteredHours':0.5,'states':state['items']},ensure_ascii=False,indent=2))
