#!/usr/bin/env python3
"""
Google Calendar checker for Echo.
Returns events for today, tomorrow, this week, or upcoming travel needs.
"""

import sys
import json
from pathlib import Path
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

TOKEN_FILE = Path(__file__).parent.parent / 'credentials' / 'google-calendar-token.json'
TZ = ZoneInfo('Europe/Bucharest')

# Keywords that indicate travel to București (needs train + accommodation)
TRAVEL_KEYWORDS = ['nlp', 'bucuresti', 'bucurești', 'bucharest']

def get_service():
    """Get authenticated Calendar service."""
    creds = Credentials.from_authorized_user_file(str(TOKEN_FILE))
    return build('calendar', 'v3', credentials=creds)

def get_events(service, time_min, time_max, max_results=20):
    """Get events between time_min and time_max."""
    events_result = service.events().list(
        calendarId='primary',
        timeMin=time_min.isoformat(),
        timeMax=time_max.isoformat(),
        maxResults=max_results,
        singleEvents=True,
        orderBy='startTime'
    ).execute()
    return events_result.get('items', [])

def format_event(event):
    """Format event for display."""
    start = event['start'].get('dateTime', event['start'].get('date'))
    summary = event.get('summary', '(fără titlu)')
    
    # Parse start time
    if 'T' in start:
        dt = datetime.fromisoformat(start)
        time_str = dt.strftime('%H:%M')
        date_str = dt.strftime('%d %b')
    else:
        time_str = 'toată ziua'
        date_str = datetime.fromisoformat(start).strftime('%d %b')
    
    return {
        'summary': summary,
        'date': date_str,
        'time': time_str,
        'start': start,
        'is_travel': any(kw in summary.lower() for kw in TRAVEL_KEYWORDS)
    }

def check_today_tomorrow():
    """Get events for today and tomorrow."""
    service = get_service()
    now = datetime.now(TZ)
    
    # Today
    today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
    today_end = today_start + timedelta(days=1)
    
    # Tomorrow
    tomorrow_end = today_end + timedelta(days=1)
    
    today_events = get_events(service, today_start, today_end)
    tomorrow_events = get_events(service, today_end, tomorrow_end)
    
    result = {
        'today': [format_event(e) for e in today_events],
        'tomorrow': [format_event(e) for e in tomorrow_events]
    }
    
    return result

def check_week():
    """Get events for this week (Mon-Sun)."""
    service = get_service()
    now = datetime.now(TZ)
    
    # Start of this week (Monday)
    days_since_monday = now.weekday()
    week_start = now.replace(hour=0, minute=0, second=0, microsecond=0) - timedelta(days=days_since_monday)
    week_end = week_start + timedelta(days=7)
    
    events = get_events(service, week_start, week_end)
    
    return {
        'week_start': week_start.strftime('%d %b'),
        'week_end': (week_end - timedelta(days=1)).strftime('%d %b'),
        'events': [format_event(e) for e in events]
    }

def check_travel_upcoming():
    """Check for travel events in next 14 days that need booking (7-11 days out)."""
    service = get_service()
    now = datetime.now(TZ)
    
    # Look 14 days ahead
    future = now + timedelta(days=14)
    events = get_events(service, now, future)
    
    reminders = []
    for event in events:
        formatted = format_event(event)
        if formatted['is_travel']:
            # Calculate days until event
            start_str = event['start'].get('dateTime', event['start'].get('date'))
            if 'T' in start_str:
                event_date = datetime.fromisoformat(start_str).date()
            else:
                event_date = datetime.fromisoformat(start_str).date()
            
            days_until = (event_date - now.date()).days
            
            # Remind if 7-11 days away (booking window)
            if 7 <= days_until <= 11:
                reminders.append({
                    **formatted,
                    'days_until': days_until,
                    'action': 'Cumpără bilete tren + asigură cazare București'
                })
            # Urgent if 3-6 days away and might have missed window
            elif 3 <= days_until <= 6:
                reminders.append({
                    **formatted,
                    'days_until': days_until,
                    'action': '⚠️ URGENT: Verifică dacă ai bilete și cazare!'
                })
    
    return {'travel_reminders': reminders}

def is_busy_now():
    """Check if there's an event happening RIGHT NOW."""
    service = get_service()
    now = datetime.now(TZ)
    
    # Check events that started before now and end after now
    events_result = service.events().list(
        calendarId='primary',
        timeMin=(now - timedelta(hours=4)).isoformat(),
        timeMax=(now + timedelta(minutes=30)).isoformat(),
        singleEvents=True,
        orderBy='startTime'
    ).execute()
    
    for event in events_result.get('items', []):
        start_str = event['start'].get('dateTime', event['start'].get('date'))
        end_str = event['end'].get('dateTime', event['end'].get('date'))
        
        # Skip all-day events for "busy now" check
        if 'T' not in start_str:
            continue
            
        start = datetime.fromisoformat(start_str)
        end = datetime.fromisoformat(end_str)
        
        if start <= now <= end:
            return {
                'busy': True,
                'event': event.get('summary', '(fără titlu)'),
                'ends': end.strftime('%H:%M')
            }
    
    return {'busy': False}

def check_upcoming_hours(hours=2):
    """Check for events in the next N hours."""
    service = get_service()
    now = datetime.now(TZ)
    future = now + timedelta(hours=hours)
    
    events = get_events(service, now, future)
    
    alerts = []
    for event in events:
        start_str = event['start'].get('dateTime', event['start'].get('date'))
        summary = event.get('summary', '(fără titlu)')
        
        if 'T' in start_str:
            start = datetime.fromisoformat(start_str)
            minutes_until = int((start - now).total_seconds() / 60)
            if minutes_until > 0:
                alerts.append({
                    'summary': summary,
                    'minutes_until': minutes_until,
                    'time': start.strftime('%H:%M')
                })
    
    return {'upcoming': alerts}

def main():
    if len(sys.argv) < 2:
        print("Usage: calendar_check.py [today|week|travel|busy|soon|all]")
        sys.exit(1)
    
    mode = sys.argv[1].lower()
    
    if mode == 'today':
        result = check_today_tomorrow()
    elif mode == 'week':
        result = check_week()
    elif mode == 'travel':
        result = check_travel_upcoming()
    elif mode == 'busy':
        result = is_busy_now()
    elif mode == 'soon':
        hours = int(sys.argv[2]) if len(sys.argv) > 2 else 2
        result = check_upcoming_hours(hours)
    elif mode == 'all':
        result = {
            **check_today_tomorrow(),
            **check_week(),
            **check_travel_upcoming()
        }
    else:
        print(f"Unknown mode: {mode}")
        sys.exit(1)
    
    print(json.dumps(result, ensure_ascii=False, indent=2))

if __name__ == '__main__':
    main()


def create_event(summary, start_datetime, duration_minutes=60, description=None, 
                 reminders=None, is_travel=False):
    """
    Create a calendar event with reminders.
    
    Args:
        summary: Event title
        start_datetime: datetime object or ISO string (e.g., "2026-02-05T15:00:00")
        duration_minutes: Duration in minutes (default 60)
        description: Optional description
        reminders: List of minutes before event for reminders, or None for defaults
                   e.g., [120, 30] = 2 hours and 30 min before
        is_travel: If True, uses travel reminders (evening before + 2h before)
    
    Returns:
        Created event details
    """
    service = get_service()
    
    # Parse start time if string
    if isinstance(start_datetime, str):
        start = datetime.fromisoformat(start_datetime)
    else:
        start = start_datetime
    
    # Ensure timezone
    if start.tzinfo is None:
        start = start.replace(tzinfo=TZ)
    
    end = start + timedelta(minutes=duration_minutes)
    
    # Set up reminders
    if reminders is None:
        if is_travel:
            # Travel: evening before (calculate minutes to 18:00 day before) + 2h before
            evening_before = start.replace(hour=18, minute=0, second=0) - timedelta(days=1)
            minutes_to_evening = int((start - evening_before).total_seconds() / 60)
            reminders = [minutes_to_evening, 120]  # Evening before + 2 hours
        else:
            # Default: 30 min before
            reminders = [30]
    
    event = {
        'summary': summary,
        'start': {
            'dateTime': start.isoformat(),
            'timeZone': 'Europe/Bucharest',
        },
        'end': {
            'dateTime': end.isoformat(),
            'timeZone': 'Europe/Bucharest',
        },
        'reminders': {
            'useDefault': False,
            'overrides': [
                {'method': 'popup', 'minutes': m} for m in reminders
            ],
        },
    }
    
    if description:
        event['description'] = description
    
    created = service.events().insert(calendarId='primary', body=event).execute()
    
    return {
        'id': created['id'],
        'summary': created['summary'],
        'start': created['start'].get('dateTime'),
        'link': created.get('htmlLink'),
        'reminders': reminders
    }
