#!/usr/bin/env python3
import json, re, requests, sys
from pathlib import Path
from datetime import datetime, date, time, timedelta
from requests.auth import HTTPBasicAuth
from icalendar import Calendar

USER = 'powellli@tencent.com'
PWD = 'ZFzx257FauBAiYLh'
BASE = 'https://caldav.wecom.work'
CAL_PATH = '/calendar/1688851418287910/'
CACHE = Path('/root/.openclaw/workspace/skills/Openclaw-With-Apple/data/wecom_caldav_index.json')
CACHE.parent.mkdir(parents=True, exist_ok=True)

def list_hrefs():
    body='''<?xml version="1.0" encoding="utf-8" ?>\n<D:propfind xmlns:D="DAV:\">\n  <D:prop><D:getetag/></D:prop>\n</D:propfind>'''
    r=requests.request('PROPFIND', BASE+CAL_PATH, data=body.encode('utf-8'), headers={'Depth':'1','Content-Type':'application/xml; charset=utf-8'}, auth=HTTPBasicAuth(USER,PWD), timeout=30)
    r.raise_for_status()
    text=r.text
    hrefs=[]
    etags={}
    parts=text.split('<D:response>')[1:]
    for part in parts:
        m=re.search(r'<D:href>(.*?)</D:href>', part)
        if not m: continue
        href=m.group(1)
        if not href.endswith('.ics'): continue
        hrefs.append(href)
        m2=re.search(r'<D:getetag>(.*?)</D:getetag>', part)
        etags[href]=m2.group(1).strip() if m2 else ''
    return hrefs, etags

def load_cache():
    if CACHE.exists():
        return json.loads(CACHE.read_text())
    return {'events':{}, 'etag':{}}

def save_cache(data):
    CACHE.write_text(json.dumps(data, ensure_ascii=False))

def parse_ics(text):
    out=[]
    try:
        cal=Calendar.from_ical(text)
        for comp in cal.walk('VEVENT'):
            summary=str(comp.get('summary','未命名'))
            dtstart=comp.get('dtstart')
            dtend=comp.get('dtend')
            location=str(comp.get('location','')) if comp.get('location') else ''
            s=dtstart.dt if dtstart else None
            e=dtend.dt if dtend else None
            if not s: continue
            if isinstance(s, date) and not isinstance(s, datetime):
                ev_start=datetime.combine(s, time.min)
                ev_end=datetime.combine((e if isinstance(e, date) else s)+timedelta(days=1), time.min) if e else ev_start+timedelta(days=1)
                all_day=True
            else:
                ev_start=s.replace(tzinfo=None) if getattr(s,'tzinfo',None) else s
                ev_end=(e.replace(tzinfo=None) if getattr(e,'tzinfo',None) else e) if e else ev_start
                all_day=False
            out.append({'start':ev_start.isoformat(sep=' '),'end':ev_end.isoformat(sep=' '),'summary':summary,'location':location,'all_day':all_day})
    except Exception:
        pass
    return out

def build_or_update(limit=None):
    cache=load_cache()
    hrefs, etags=list_hrefs()
    changed=[]
    for href in hrefs:
        if cache['etag'].get(href) != etags.get(href):
            changed.append(href)
    if limit:
        changed=changed[-limit:]
    for i,href in enumerate(changed,1):
        r=requests.get(BASE+href, auth=HTTPBasicAuth(USER,PWD), timeout=15)
        if r.status_code==200:
            cache['events'][href]=parse_ics(r.text)
            cache['etag'][href]=etags.get(href,'')
    save_cache(cache)
    return cache, len(hrefs), len(changed)

def query_day(day_str):
    target=datetime.strptime(day_str, '%Y-%m-%d').date()
    start_dt=datetime.combine(target, time.min)
    end_dt=datetime.combine(target + timedelta(days=1), time.min)
    cache=load_cache()
    items=[]
    for href, evs in cache.get('events',{}).items():
        for ev in evs:
            s=datetime.fromisoformat(ev['start'])
            e=datetime.fromisoformat(ev['end'])
            if s < end_dt and e > start_dt:
                items.append(ev)
    items=sorted({(x['start'],x['end'],x['summary'],x['location'],x['all_day']) for x in items})
    for s,e,summary,location,all_day in items:
        if all_day:
            print(f'ALLDAY\t{summary}\t{location}')
        else:
            ss=datetime.fromisoformat(s).strftime('%H:%M')
            ee=datetime.fromisoformat(e).strftime('%H:%M')
            print(f'{ss}-{ee}\t{summary}\t{location}')
    print(f'COUNT\t{len(items)}')

if __name__=='__main__':
    cmd=sys.argv[1]
    if cmd=='index':
        limit=int(sys.argv[2]) if len(sys.argv)>2 else None
        cache,total,changed=build_or_update(limit)
        print(f'TOTAL\t{total}')
        print(f'UPDATED\t{changed}')
    elif cmd=='query':
        query_day(sys.argv[2])
