#!/usr/bin/env python3
import json
import re
from datetime import datetime
from pathlib import Path

WORKSPACE = Path('/home/isthekid/.openclaw/workspace')
SESSIONS_DIR = Path('/home/isthekid/.openclaw/agents/main/sessions')
STATE_PATH = WORKSPACE / 'monitoring/state/telegram_lag_state.json'
LOG_PATH = WORKSPACE / 'monitoring/telegram_lag_log.jsonl'
ALERT_PATH = WORKSPACE / 'monitoring/telegram_lag_alerts.jsonl'
TARGET_SENDER = '8340647700'
LAG_ALERT_SECONDS = 120

TS_RE = re.compile(r'"timestamp"\s*:\s*"([^"]+)"')
MID_RE = re.compile(r'"message_id"\s*:\s*"?(\d+)"?')
SID_RE = re.compile(r'"sender_id"\s*:\s*"?(\d+)"?')


def load_state():
    if STATE_PATH.exists():
        try:
            return json.loads(STATE_PATH.read_text())
        except Exception:
            pass
    return {'last_processed_mid': 0}


def save_state(state):
    STATE_PATH.parent.mkdir(parents=True, exist_ok=True)
    STATE_PATH.write_text(json.dumps(state, indent=2))


def parse_source_ts(text):
    m = TS_RE.search(text)
    if not m:
        return None
    raw = m.group(1).strip()
    # Example: Tue 2026-03-17 20:31 EDT
    for fmt in ('%a %Y-%m-%d %H:%M EDT', '%a %Y-%m-%d %H:%M EST'):
        try:
            return datetime.strptime(raw, fmt)
        except Exception:
            continue
    return None


def parse_meta(text):
    sid = None
    mid = None
    s = SID_RE.search(text)
    if s:
        sid = s.group(1)
    m = MID_RE.search(text)
    if m:
        mid = int(m.group(1))
    return sid, mid


def iter_jsonl(path):
    with path.open('r', encoding='utf-8', errors='ignore') as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            try:
                yield json.loads(line)
            except Exception:
                continue


def find_latest_main_transcript():
    # Most recently modified transcript file for main session
    files = sorted(SESSIONS_DIR.glob('*.jsonl'), key=lambda p: p.stat().st_mtime, reverse=True)
    return files[0] if files else None


def append_jsonl(path, obj):
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open('a', encoding='utf-8') as f:
        f.write(json.dumps(obj, ensure_ascii=False) + '\n')


def main():
    state = load_state()
    last_mid = int(state.get('last_processed_mid', 0))

    transcript = find_latest_main_transcript()
    if not transcript:
        return

    max_seen = last_mid

    for row in iter_jsonl(transcript):
        if row.get('type') != 'message':
            continue
        msg = row.get('message', {})
        if msg.get('role') != 'user':
            continue
        contents = msg.get('content', [])
        text = '\n'.join(c.get('text', '') for c in contents if isinstance(c, dict))
        if not text:
            continue

        sender_id, message_id = parse_meta(text)
        if sender_id != TARGET_SENDER or not message_id:
            continue
        if message_id <= last_mid:
            continue

        recv_iso = row.get('timestamp')  # ISO Z
        try:
            recv_dt = datetime.fromisoformat(recv_iso.replace('Z', '+00:00')).astimezone()
        except Exception:
            continue

        src_dt = parse_source_ts(text)
        if not src_dt:
            continue

        # Source timestamp is ET local time string; compare naive to local ET by replacing tz
        # Approximate by interpreting src_dt as local timezone wall clock.
        lag_seconds = int((recv_dt.replace(tzinfo=None) - src_dt).total_seconds())

        rec = {
            'message_id': message_id,
            'sender_id': sender_id,
            'source_timestamp': src_dt.strftime('%Y-%m-%d %H:%M:%S ET'),
            'received_timestamp': recv_dt.isoformat(),
            'lag_seconds': lag_seconds,
            'transcript': str(transcript),
            'checked_at': datetime.now().isoformat()
        }
        append_jsonl(LOG_PATH, rec)

        if lag_seconds >= LAG_ALERT_SECONDS:
            alert = dict(rec)
            alert['severity'] = 'warn'
            alert['reason'] = 'inbound_delivery_lag'
            append_jsonl(ALERT_PATH, alert)

        if message_id > max_seen:
            max_seen = message_id

    state['last_processed_mid'] = max_seen
    save_state(state)


if __name__ == '__main__':
    main()
