#!/usr/bin/env python3
"""
Google Calendar integration for Rivet.
Fetches today's and tomorrow's events, checks for conflicts, and saves summary.
"""

import json
import os
import sys
import requests
import subprocess
from datetime import datetime, timedelta, timezone
import pytz

# Configuration
OAUTH_FILE = "/root/.clawdbot/google-oauth.json"
REFRESH_SCRIPT = "/home/ccuser/rateright-growth/rivet/scripts/google-refresh.py"
OUTPUT_FILE = "/home/ccuser/rateright-growth/rivet/memory/calendar-summary.md"
CALENDAR_API = "https://www.googleapis.com/calendar/v3/calendars/primary/events"

# Timezone
SYDNEY_TZ = pytz.timezone('Australia/Sydney')

def read_oauth_token():
    """Read access token from OAuth file"""
    try:
        with open(OAUTH_FILE, 'r') as f:
            oauth_data = json.load(f)
        return oauth_data.get('access_token')
    except (FileNotFoundError, json.JSONDecodeError) as e:
        print(f"Error reading OAuth file: {e}")
        return None

def refresh_and_get_token():
    """Refresh token and return new access token"""
    print("Token expired or invalid. Refreshing...")
    try:
        # Run refresh script
        result = subprocess.run([REFRESH_SCRIPT], capture_output=True, text=True)
        if result.returncode != 0:
            print(f"Error refreshing token: {result.stderr}")
            return None
        
        # Read new token
        return read_oauth_token()
    except Exception as e:
        print(f"Error running refresh script: {e}")
        return None

def get_calendar_events(access_token, time_min, time_max):
    """Fetch events from Google Calendar API"""
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Accept': 'application/json'
    }
    
    params = {
        'timeMin': time_min.isoformat(),
        'timeMax': time_max.isoformat(),
        'singleEvents': 'true',
        'orderBy': 'startTime',
        'maxResults': 50
    }
    
    try:
        response = requests.get(CALENDAR_API, headers=headers, params=params)
        
        if response.status_code == 401:
            # Token expired
            return None, 'expired'
        elif response.status_code != 200:
            print(f"API error: {response.status_code}")
            print(response.text)
            return None, 'error'
        
        return response.json(), 'success'
    except Exception as e:
        print(f"Error fetching calendar events: {e}")
        return None, 'error'

def parse_event_time(event_time, timezone_info):
    """Parse event time (dateTime or date) to datetime object"""
    if 'dateTime' in event_time:
        # Has specific time
        dt = datetime.fromisoformat(event_time['dateTime'].replace('Z', '+00:00'))
        if dt.tzinfo is None:
            dt = dt.replace(tzinfo=timezone.utc)
        return dt.astimezone(timezone_info)
    else:
        # All-day event (date only)
        date_str = event_time['date']
        dt = datetime.strptime(date_str, '%Y-%m-%d')
        return timezone_info.localize(dt)

def format_time(dt):
    """Format datetime for display"""
    if dt.hour == 0 and dt.minute == 0:
        # All-day event
        return dt.strftime('%a %b %d (All day)')
    else:
        return dt.strftime('%a %b %d, %I:%M %p')

def find_conflicts(events):
    """Find overlapping events (conflicts)"""
    conflicts = []
    
    # Sort events by start time
    sorted_events = sorted(events, key=lambda x: x['start_dt'])
    
    for i in range(len(sorted_events)):
        for j in range(i + 1, len(sorted_events)):
            event1 = sorted_events[i]
            event2 = sorted_events[j]
            
            # Check if events overlap
            if event1['end_dt'] > event2['start_dt'] and event2['end_dt'] > event1['start_dt']:
                conflicts.append((event1, event2))
    
    return conflicts

def generate_summary(events, conflicts, date_range_str):
    """Generate formatted summary markdown"""
    now = datetime.now(SYDNEY_TZ)
    
    summary = f"""# Calendar Summary
*Generated: {now.strftime('%Y-%m-%d %H:%M %Z')}*
*Date Range: {date_range_str}*

## 📅 Events Summary
"""
    
    if not events:
        summary += "No events scheduled.\n"
    else:
        # Group by day
        events_by_day = {}
        for event in events:
            day_key = event['start_dt'].strftime('%Y-%m-%d')
            if day_key not in events_by_day:
                events_by_day[day_key] = []
            events_by_day[day_key].append(event)
        
        # Sort days
        for day_key in sorted(events_by_day.keys()):
            day_events = events_by_day[day_key]
            day_date = day_events[0]['start_dt']
            
            summary += f"\n### {day_date.strftime('%A, %B %d')}\n"
            
            for event in day_events:
                summary += f"- **{event['title']}**\n"
                summary += f"  ⏰ {format_time(event['start_dt'])} - {format_time(event['end_dt'])}\n"
                if event.get('location'):
                    summary += f"  📍 {event['location']}\n"
                if event.get('description'):
                    # Truncate description
                    desc = event['description']
                    if len(desc) > 150:
                        desc = desc[:147] + "..."
                    summary += f"  📝 {desc}\n"
                summary += "\n"
    
    # Add conflicts section if any
    if conflicts:
        summary += "\n## ⚠️ Schedule Conflicts\n"
        for event1, event2 in conflicts:
            summary += f"- **{event1['title']}** conflicts with **{event2['title']}**\n"
            summary += f"  {format_time(event1['start_dt'])} - {format_time(event1['end_dt'])} overlaps with "
            summary += f"{format_time(event2['start_dt'])} - {format_time(event2['end_dt'])}\n\n"
    
    # Add statistics
    summary += f"\n## 📊 Statistics\n"
    summary += f"- Total events: {len(events)}\n"
    summary += f"- Conflicts detected: {len(conflicts)}\n"
    
    # Add next event if available
    future_events = [e for e in events if e['start_dt'] > now]
    if future_events:
        next_event = min(future_events, key=lambda x: x['start_dt'])
        time_until = next_event['start_dt'] - now
        hours = int(time_until.total_seconds() // 3600)
        minutes = int((time_until.total_seconds() % 3600) // 60)
        
        summary += f"\n## ⏭️ Next Up\n"
        summary += f"- **{next_event['title']}** in {hours}h {minutes}m\n"
        summary += f"  Starts: {format_time(next_event['start_dt'])}\n"
    
    return summary

def main():
    print("Starting calendar check...")
    
    # Get access token
    access_token = read_oauth_token()
    if not access_token:
        print("No access token found")
        sys.exit(1)
    
    # Calculate time range (today and tomorrow in Sydney timezone)
    now_sydney = datetime.now(SYDNEY_TZ)
    
    # Today: from midnight to midnight
    today_start = now_sydney.replace(hour=0, minute=0, second=0, microsecond=0)
    today_end = today_start + timedelta(days=1)
    
    # Tomorrow: next midnight to midnight
    tomorrow_start = today_end
    tomorrow_end = tomorrow_start + timedelta(days=1)
    
    # We'll fetch both days in one call
    time_min = today_start
    time_max = tomorrow_end
    
    date_range_str = f"{today_start.strftime('%Y-%m-%d')} to {tomorrow_end.strftime('%Y-%m-%d')}"
    
    # Fetch events
    events_data, status = get_calendar_events(access_token, time_min, time_max)
    
    # Handle token expiration
    if status == 'expired':
        access_token = refresh_and_get_token()
        if not access_token:
            print("Failed to refresh token")
            sys.exit(1)
        
        # Retry with new token
        events_data, status = get_calendar_events(access_token, time_min, time_max)
        if status != 'success':
            print("Failed to fetch events after token refresh")
            sys.exit(1)
    
    if status != 'success' or not events_data:
        print("Failed to fetch calendar events")
        sys.exit(1)
    
    # Parse events
    all_events = []
    for item in events_data.get('items', []):
        try:
            title = item.get('summary', 'No title')
            start_dt = parse_event_time(item['start'], SYDNEY_TZ)
            end_dt = parse_event_time(item['end'], SYDNEY_TZ)
            
            # Skip events that end before our time range starts
            if end_dt <= time_min:
                continue
            
            event = {
                'title': title,
                'start_dt': start_dt,
                'end_dt': end_dt,
                'location': item.get('location', ''),
                'description': item.get('description', ''),
                'id': item.get('id', '')
            }
            all_events.append(event)
        except Exception as e:
            print(f"Error parsing event: {e}")
            continue
    
    # Find conflicts
    conflicts = find_conflicts(all_events)
    
    # Generate summary
    summary = generate_summary(all_events, conflicts, date_range_str)
    
    # Save to file
    try:
        os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True)
        with open(OUTPUT_FILE, 'w') as f:
            f.write(summary)
        print(f"Calendar summary saved to {OUTPUT_FILE}")
        
        # Print brief summary to console
        print(f"\n📅 Calendar Check Complete:")
        print(f"   Events found: {len(all_events)}")
        print(f"   Conflicts: {len(conflicts)}")
        if all_events:
            next_event = min(all_events, key=lambda x: x['start_dt'])
            print(f"   Next event: {next_event['title']} at {format_time(next_event['start_dt'])}")
        
    except Exception as e:
        print(f"Error saving summary: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()