#!/usr/bin/env python3
"""Notion ↔ 代码仓库双向同步器"""
import os, sys, json, time, subprocess
from datetime import datetime
try: import requests
except: print('pip install requests'); sys.exit(1)

NOTION_TOKEN = os.environ.get('NOTION_TOKEN') or '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'
# 数据库URL中的ID（不是集合ID）
NOTION_DATABASE_ID = '663e4f29c7404d088f3a02fcc70b1418'
REPO_PATH = '/opt/guanghulab-repo'
DB_PATH = os.path.join(REPO_PATH, 'persona-brain-db', 'brain.db')
CACHE_FILE = os.path.join(REPO_PATH, 'notion', 'tickets-cache.json')
INTERVAL = int(os.environ.get('SYNC_INTERVAL', '1800'))
HEADERS = {'Authorization': f'Bearer {NOTION_TOKEN}', 'Notion-Version': '2022-06-28', 'Content-Type': 'application/json'}

def log(m): print(f'[{datetime.now().strftime("%H:%M:%S")}] {m}', flush=True)

def query():
    url = f'https://api.notion.com/v1/databases/{NOTION_DATABASE_ID}/query'
    body = {'page_size': 50, 'sorts': [{'timestamp': 'last_edited_time', 'direction': 'descending'}]}
    try:
        r = requests.post(url, headers=HEADERS, json=body, timeout=15)
        if r.status_code == 401: log('Token过期'); return []
        if not r.ok: log(f'API错误 {r.status_code}'); return []
        return r.json().get('results', [])
    except Exception as e: log(f'异常: {e}'); return []

def get_mine(tickets):
    mine = []
    for t in tickets:
        p = t.get('properties', {})
        agent = p.get('负责Agent', {}).get('select', {}).get('name', '')
        status = p.get('状态', {}).get('select', {}).get('name', '')
        title = p.get('任务标题', {}).get('title', [{}])[0].get('plain_text', '?')
        code = p.get('编号', {}).get('rich_text', [{}])[0].get('plain_text', '') if not p.get('编号', {}).get('type') else ''
        if agent in ('铸渊', '') and status not in ('已完成', '暂缓'):
            mine.append({'page_id': t['id'], 'title': title, 'status': status, 'agent': agent, 'url': t.get('url', ''), 'code': code})
    return mine

def sync_cycle():
    log('=' * 40)
    tickets = query()
    if not tickets: return
    mine = get_mine(tickets)
    if mine:
        log(f'铸渊相关工单: {len(mine)} 条')
        for item in mine:
            log(f'  [{item["status"]}] {item["agent"]} | {item["title"][:40]}')
    else:
        log('无铸渊相关工单')
    try:
        with open(CACHE_FILE, 'w') as f:
            json.dump({'last_sync': datetime.now().isoformat(), 'tickets': [{'id': t['id'], 'title': t.get('properties',{}).get('任务标题',{}).get('title',[{}])[0].get('plain_text',''), 'status': t.get('properties',{}).get('状态',{}).get('select',{}).get('name','')} for t in tickets]}, f, ensure_ascii=False, indent=2)
    except: pass
    log('同步完成')

if __name__ == '__main__':
    log(f'Notion同步器启动 | 间隔{INTERVAL//60}分钟 | 数据库: {NOTION_DATABASE_ID[:12]}...')
    sync_cycle()
    try:
        while True:
            time.sleep(INTERVAL)
            sync_cycle()
    except KeyboardInterrupt: log('停止')
