#!/usr/bin/env python3
"""
Export Discord channel history using the message tool via subprocesses.
Since direct Discord API is blocked by Cloudflare, we'll use curl through openclaw.
"""
import json, os, sys, time, subprocess

# We already have the channel list from the message tool output. Hardcode the active channels.
CHANNELS = [
    # (id, name, category)
    ("1470382284988219593", "management", ""),
    ("1467975707106738290", "curious-endeavor", "Curious Endeavor"),
    ("1467975831958716466", "radar", "Methodology"),
    ("1474317373954850917", "visual-methodology", "Methodology"),
    ("1484222491466535024", "competitive-research", "CE Products"),
    ("1478351008584437892", "open-tasks", "Active Work"),
    ("1478351010240921813", "ideas-backlog", "Active Work"),
    ("1478351011939881128", "dev-projects", "Active Work"),
    ("1478672759520497735", "emails-and-cals-scan", "Active Work"),
    ("1484301426082709534", "ce-website", "Active Work"),
    ("1468572400516862128", "ce-social", "Curious Endeavor"),
    ("1474317369567350924", "visual-input", "Curious Endeavor"),
    ("1478412389216030720", "skills-development", "Curious Endeavor"),
    ("1486804429884752074", "figma", "Curious Endeavor"),
    ("1482832945617047653", "portoflio", "Curious Endeavor"),
    ("1467975644540440666", "spoken-institute", "Projects"),
    ("1467975670591389938", "phat-foods", "Projects"),
    ("1468749410040025120", "mission", "Projects"),
    ("1489287014900826203", "mission-2", "Projects"),
    ("1473404518732529856", "etoro", "Projects"),
    ("1472894132664926322", "team8", "Projects"),
    ("1473398524816392192", "lobster", "Projects"),
    ("1479149634176811120", "verifone", "Projects"),
    ("1476511995372245115", "fioner", "Projects"),
    ("1476558140551069726", "hud", "Projects"),
    ("1479470173869178911", "lukas-things", "Projects"),
    ("1480576260580315186", "jviewz", "Projects"),
    ("1469611095718367262", "autonomous-agency", "Projects"),
    ("1467974389331918957", "general", "Workspace"),
    ("1467975853257392128", "tasks", "Workspace"),
    ("1471853662975426735", "claude-for-figma", "Workspace"),
    ("1478122833162010746", "image-creation", "Workspace"),
    ("1477163482406322247", "strategy-document", "Workspace"),
    ("1468321288937541845", "improvement", "HQ"),
    ("1474030741821194251", "contacts-from-site", "HQ"),
    ("1478855000535990282", "admin", "HQ"),
    ("1479059150792294462", "brain-maintenance", "HQ"),
    ("1481943431801737217", "ce-finance", "HQ"),
    ("1489572849642504323", "2025-tax", "HQ"),
    ("1482100301434589337", "brandwatch", ""),
    ("1482219065199300710", "lukas-kitt", ""),
    ("1482763486156296282", "amir", ""),
    ("1484183292021575822", "gerri", ""),
    ("1485600222208983231", "wix-pitch", "Active Work"),
    ("1487376032196464850", "client-support", "Active Work"),
    ("1473557554125869280", "methodology", "Methodology"),
    ("1474317370871779380", "taste-development", "Methodology"),
    ("1478515767069769942", "skills-review", "Methodology"),
    ("1483847265146896484", "skills-improvement-karpathy", "Methodology"),
    ("1483917646389837997", "marquez", "Home fronteira"),
    ("1485175570995351734", "office", "Home fronteira"),
    ("1488473971216224287", "club-7", "Home fronteira"),
    ("1488504485772001381", "basket", "Home fronteira"),
    ("1485742822966427701", "product-definition", "Productize"),
    ("1486032243330908321", "fiona-protocol-v2-test", "Productize"),
    ("1485891369024094283", "brand-pipeline-spec", ""),
    ("1479166501452906691", "logo-maker-machine", "Methodology"),
]

OUTPUT_DIR = '/root/.openclaw/workspace/discord-history'
TOKEN = None

def load_token():
    global TOKEN
    with open('/root/.openclaw/openclaw.json') as f:
        config = json.load(f)
    TOKEN = config['channels']['discord']['accounts']['kitt']['token']

def fetch_messages(channel_id, before=None, limit=100):
    """Fetch messages using Discord API through the bot token."""
    import urllib.request, urllib.error
    url = f'https://discord.com/api/v10/channels/{channel_id}/messages?limit={limit}'
    if before:
        url += f'&before={before}'
    headers = {'Authorization': f'Bot {TOKEN}', 'User-Agent': 'DiscordBot (private, 1.0)'}
    req = urllib.request.Request(url, headers=headers)
    try:
        with urllib.request.urlopen(req) as resp:
            return json.loads(resp.read())
    except urllib.error.HTTPError as e:
        if e.code == 429:
            body = json.loads(e.read())
            wait = body.get('retry_after', 2)
            print(f"    Rate limited, waiting {wait}s...")
            time.sleep(wait + 0.5)
            return fetch_messages(channel_id, before, limit)
        print(f"    HTTP {e.code}")
        return []

def get_all_messages(channel_id, name):
    msgs = []
    before = None
    while True:
        batch = fetch_messages(channel_id, before)
        if not batch:
            break
        msgs.extend(batch)
        sys.stdout.write(f"\r    #{name}: {len(msgs)} messages...")
        sys.stdout.flush()
        if len(batch) < 100:
            break
        before = batch[-1]['id']
        time.sleep(0.5)
    print(f"\r    #{name}: {len(msgs)} messages total        ")
    msgs.reverse()
    return msgs

def format_msg(m):
    author = m['author'].get('global_name') or m['author'].get('username', '?')
    ts = m['timestamp'][:16].replace('T', ' ')
    content = m.get('content', '') or ''
    parts = [f"**{author}** ({ts})"]
    if content:
        parts.append(content)
    for a in m.get('attachments', []):
        parts.append(f"📎 {a.get('filename', 'file')}")
    for e in m.get('embeds', []):
        t = e.get('title', '')
        d = (e.get('description', '') or '')[:150]
        if t or d:
            parts.append(f"[embed: {t} — {d}]")
    parts.append('')
    return '\n'.join(parts)

def export():
    load_token()
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    total = 0
    
    for ch_id, name, cat in CHANNELS:
        print(f"  Exporting #{name}...")
        msgs = get_all_messages(ch_id, name)
        if not msgs:
            print(f"    (empty/no access)")
            continue
        
        subdir = os.path.join(OUTPUT_DIR, cat.replace(' ', '-').lower()) if cat else OUTPUT_DIR
        os.makedirs(subdir, exist_ok=True)
        
        path = os.path.join(subdir, f'{name}.md')
        with open(path, 'w') as f:
            f.write(f'# #{name}\n\n')
            for m in msgs:
                f.write(format_msg(m))
        
        total += len(msgs)
        time.sleep(0.3)
    
    print(f"\n✅ Exported {total} messages across {len(CHANNELS)} channels")
    print(f"📁 Location: {OUTPUT_DIR}")

if __name__ == '__main__':
    export()
