"""Submit Codeup review, audited effort and Yunxiao status/comments with readback."""
import json
from datetime import datetime, timezone
from sync import api, PREFIX, ORG, compact, state, WORK, rows

BRANCH = 'codex/VWCG-1455-report-department-select-20261019'
COMMIT = 'ae82cb12e382f1d0ebd70c51f306a432bcfdb003'
STYLE_COMMIT = 'bf5b71ceb9e52d5ddef990c31a9d3a65c0e93728'
OWNER = state['parent']['assignedTo']['id']
DEV = state['tasks']['development']
QA = state['tasks']['validation']
PARENT = state['parent']
RESULT_PATH = WORK / 'submission.sanitized.json'
result = json.loads(RESULT_PATH.read_text()) if RESULT_PATH.exists() else {}

def save():
    RESULT_PATH.write_text(json.dumps(result, ensure_ascii=False, indent=2) + '\n')

validation = 'Node14.21.3前端单元测试13 suites/59 tests通过；真实ElementUI组件点击、五类axios请求参数捕获通过；标准Node14生产构建通过；git diff --check通过。'
remaining = '人员报表已完成真实浏览器组合操作；部门/设备/充值/补贴完整页面点击、实际异步Excel下载核对和最终订单样式视觉回读待补。未宣称这些环境验收通过。'
mr_description = f'''统计报表五类页面部门下拉增加全选、反选快捷文字；保留普通部门勾选。消费汇总type2/3/4保持department_uuids，充值/补贴type5/6保持department_uuid，操作标识不进入请求。共享末级收集和参数序列化工具。

关联：VWCG-1454（父需求）、VWCG-1455（开发）、VWCG-1456（验收）；附带VWCG-1452消费订单快捷操作样式一致性修复，采用独立提交。

验证：{validation}
待验：{remaining}
不涉及后端、数据库、数据权限及订单/充值/补贴资金写入。目标分支按国信项目既有约定为guoxin_develop，未合并或部署。
'''
mr_prefix = f'/oapi/v1/codeup/organizations/{ORG}/repositories/4913137/changeRequests'
if not result.get('mr'):
    mr = api('POST', mr_prefix, {
        'title': '#VWCG-1455 五类统计报表部门全选反选及样式统一',
        'description': mr_description,
        'sourceProjectId': 4913137, 'targetProjectId': 4913137,
        'sourceBranch': BRANCH, 'targetBranch': 'guoxin_develop',
        'createFrom': 'WEB', 'workInProgress': False,
        'workItemIds': [PARENT['id'], DEV['id'], QA['id'], '8e060f2ce4fa7f2323a31b7146'],
    })
    assert mr.get('localId')
    result['mr'] = {k: mr.get(k) for k in ['localId', 'detailUrl', 'title', 'sourceBranch', 'targetBranch', 'status', 'ahead', 'behind', 'allRequirementsPass']}
    save()
mr = api('GET', mr_prefix + '/' + str(result['mr']['localId']))
assert mr['sourceBranch'] == BRANCH and mr['targetBranch'] == 'guoxin_develop'
assert mr['ahead'] == 2 and mr['behind'] == 0
result['mr'] = {k: mr.get(k) for k in ['localId', 'detailUrl', 'title', 'sourceBranch', 'targetBranch', 'status', 'ahead', 'behind', 'allRequirementsPass', 'conflictCheckStatus']}
save()

for item in [PARENT, DEV, QA]:
    workflow = api('GET', PREFIX + '/workitems/' + item['id'] + '/workflow')
    result.setdefault('workflows', {})[item['serialNumber']] = workflow['statuses']
save()

# Only the current task's timing events are read; no conversation bodies are archived.
log = '/Users/wiscourper/.codex/sessions/2026/09/21/rollout-2026-09-21T16-36-50-01a02358-b448-70e1-ac3b-c63771a17523_01a0c31c-5a83-78f1-ab6c-323579e608bc.jsonl'
turns = {}
for line in open(log):
    try:
        row = json.loads(line)
    except ValueError:
        continue
    if not row.get('timestamp', '').startswith('2026-10-19') or row.get('type') != 'event_msg':
        continue
    payload = row.get('payload', {})
    if payload.get('type') not in ['task_started', 'task_complete', 'turn_aborted']:
        continue
    entry = turns.setdefault(payload.get('turn_id'), {})
    entry['start' if payload['type'] == 'task_started' else 'end'] = row['timestamp']

def parsed(value):
    return datetime.fromisoformat(value.replace('Z', '+00:00'))

def interval(turn_id):
    value = turns[turn_id]
    return {'start': value['start'], 'end': value.get('end', datetime.now(timezone.utc).isoformat())}

if not result.get('effortPlan'):
    slices = {
        'development': [interval('01a151fb-d591-7181-90c9-70c8bf7a1f09'), interval('01a1520e-f706-70c3-a08a-8d6c45a0476d')],
        'validation': [interval('01a15213-9103-76d0-be3f-c4606f717029')],
        'style': [interval('01a1520a-0010-7293-8e72-8d7d514109fa')],
    }
    result['effortPlan'] = {}
    for key, intervals in slices.items():
        seconds = sum((parsed(x['end']) - parsed(x['start'])).total_seconds() for x in intervals)
        result['effortPlan'][key] = {'intervals': intervals, 'seconds': round(seconds, 3), 'hours': round(seconds / 3600, 1)}
    save()

def ensure_effort(item_id, key, marker, label):
    path = PREFIX + '/workitems/' + item_id + '/effortRecords'
    existing = [x for x in rows(api('GET', path)) if marker in (x.get('description') or '')]
    assert len(existing) <= 1
    plan = result['effortPlan'][key]
    if not existing:
        starts = [parsed(x['start']) for x in plan['intervals']]
        ends = [parsed(x['end']) for x in plan['intervals']]
        api('POST', path, {
            'operatorId': OWNER, 'actualTime': plan['hours'],
            'gmtStart': int(min(starts).timestamp() * 1000), 'gmtEnd': int(max(ends).timestamp() * 1000),
            'description': marker + ' ' + label + '；依据本线程对应task_started至task_complete有效时段，包含分析/方案，剔除轮次间用户等待，未叠加任何并行时间；0.1h登记。',
        })
    matches = [x for x in rows(api('GET', path)) if marker in (x.get('description') or '')]
    assert len(matches) == 1 and matches[0]['owner']['id'] == OWNER
    assert float(matches[0]['actualTime']) == plan['hours']
    return {k: matches[0].get(k) for k in ['id', 'actualTime', 'gmtStart', 'gmtEnd', 'description', 'owner']}

result['efforts'] = {
    'development': ensure_effort(DEV['id'], 'development', 'VWCG1454-IMPL-20261019', '五报表需求核验、方案、实现、单元测试、构建与组件验证'),
    'validation': ensure_effort(QA['id'], 'validation', 'VWCG1454-DELIVERY-20261019', '云效UC与任务拆解、计划工时、代码审查提交关联和交付复核（截至登记时；后续环境验收未预填）'),
    'style': ensure_effort('8e060f2ce4fa7f2323a31b7146', 'style', 'VWCG1452-STYLE-20261019', '消费订单快捷操作样式核验修正与Node14测试构建'),
}
save()

status_targets = {PARENT['id']: '1dec9023be7be6cf79e6bde901', DEV['id']: '100011', QA['id']: '100010'}
for item_id, status in status_targets.items():
    statuses = api('GET', PREFIX + '/workitems/' + item_id + '/workflow')['statuses']
    assert any(s['id'] == status for s in statuses)
    api('PUT', PREFIX + '/workitems/' + item_id, {'status': status})

def ensure_comment(item_id, marker, content):
    path = PREFIX + '/workitems/' + item_id + '/comments'
    def comments():
        data = api('GET', path)
        return data if isinstance(data, list) else (data or {}).get('comments', (data or {}).get('result', []))
    existing = [x for x in comments() if marker in str(x.get('content', x.get('comment', '')))]
    if not existing:
        api('POST', path, {'content': marker + '\n' + content})
    matches = [x for x in comments() if marker in str(x.get('content', x.get('comment', '')))]
    assert len(matches) == 1
    return matches[0]['id']

dev_hours = result['efforts']['development']['actualTime']
qa_hours = result['efforts']['validation']['actualTime']
common = f'''UC-REPORT-022/023 v1.0，覆盖M1-M4/A1-A3/E1-E2/R1，AC1-AC4代码已实现。
代码提交：{COMMIT}（#VWCG-1455 五类统计报表部门筛选支持全选反选）。
附带独立提交：{STYLE_COMMIT}（#VWCG-1452 统一部门快捷操作样式去除禁用框）。
远端任务分支：{BRANCH}；Codeup MR：{mr['detailUrl']}，目标guoxin_develop，ahead=2/behind=0，无冲突。
验证：{validation}
待验：{remaining}
计划2026-10-19开始/完成；无AI预计开发4h+验收2h，实际开发{dev_hours}h+交付复核{qa_hours}h，均包含方案/分析，按真实有效执行时段回读。
状态：父需求待测试；开发任务{DEV['serialNumber']}开发完成；验收任务{QA['serialNumber']}处理中。
本地工作区保留guoxin_develop且已包含全部代码；仅推送任务分支，未合并远程guoxin_develop、未部署。
'''
result['commentIds'] = {}
for item in [PARENT, DEV, QA]:
    result['commentIds'][item['serialNumber']] = ensure_comment(item['id'], 'VWCG1454-SUBMISSION-20261019', common)
result['styleComment'] = ensure_comment('8e060f2ce4fa7f2323a31b7146', 'VWCG1452-STYLE-SUBMISSION-20261019', f'消费订单灰色操作框与图标修正已提交{STYLE_COMMIT}，关联代码评审{mr["detailUrl"]}；此次样式附加工时{result["efforts"]["style"]["actualTime"]}h，未改接口/选择/导出逻辑。')

result['items'] = {}
for item in [PARENT, DEV, QA]:
    readback = api('GET', PREFIX + '/workitems/' + item['serialNumber'])
    result['items'][item['serialNumber']] = {
        **compact(readback),
        'fields': {x['fieldId']: x.get('values') for x in readback.get('customFieldValues', []) if x.get('fieldId') in ['79', '80', '101586', '101587', 'sumPlanedLaborHour', 'sumActualLaborHour']},
    }
result['mr'] = {k: api('GET', mr_prefix + '/' + str(mr['localId'])).get(k) for k in ['localId', 'detailUrl', 'title', 'sourceBranch', 'targetBranch', 'status', 'ahead', 'behind', 'allRequirementsPass', 'conflictCheckStatus']}
result['commit'] = COMMIT
result['styleCommit'] = STYLE_COMMIT
save()
print(json.dumps({'items': result['items'], 'effortHours': {k: v['actualTime'] for k, v in result['efforts'].items()}, 'mr': result['mr']}, ensure_ascii=False, indent=2))
