"""
Google Calendar Integration for Google Chat Bot
Provides calendar functionality through the chat interface
"""

import asyncio
import logging
from datetime import datetime, timedelta
from typing import Dict, Any, List, Optional
import sys
import os

# Add the project root to the Python path
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../')))

from src.providers.google_calendar.api.calendar import GoogleCalendarAPI

logger = logging.getLogger(__name__)

class GoogleCalendarIntegration:
    """Google Calendar integration for the chat bot"""
    
    def __init__(self):
        self.calendar_api = GoogleCalendarAPI()
    
    async def list_calendars(self) -> str:
        """List all accessible calendars"""
        try:
            calendars = self.calendar_api.list_calendars()
            
            if isinstance(calendars, dict) and "error" in calendars:
                return f"❌ Error listing calendars: {calendars['error']}"
            
            if not calendars:
                return "📅 No calendars found or access denied."
            
            result = "📅 *Available Calendars*\n\n"
            for i, calendar in enumerate(calendars[:10], 1):  # Limit to 10
                name = calendar.get('summary', 'Unnamed Calendar')
                calendar_id = calendar.get('id', 'Unknown')
                primary = " (Primary)" if calendar.get('primary', False) else ""
                
                result += f"{i}. *{name}*{primary}\n"
                result += f"   ID: `{calendar_id}`\n"
                if calendar.get('description'):
                    result += f"   Description: {calendar['description']}\n"
                result += "\n"
            
            if len(calendars) > 10:
                result += f"... and {len(calendars) - 10} more calendars"
            
            return result
            
        except Exception as e:
            logger.error(f"Error listing calendars: {e}")
            return f"❌ Error listing calendars: {str(e)}"
    
    async def list_events(self, calendar_id: str = 'primary', days: int = 7) -> str:
        """List events for a calendar"""
        try:
            # Calculate time range
            now = datetime.utcnow()
            time_min = now.isoformat() + 'Z'
            time_max = (now + timedelta(days=days)).isoformat() + 'Z'
            
            events = self.calendar_api.list_events(
                calendar_id=calendar_id,
                max_results=20,
                time_min=time_min,
                time_max=time_max
            )
            
            if isinstance(events, dict) and "error" in events:
                return f"❌ Error listing events: {events['error']}"
            
            if not events:
                return f"📅 No events found in the next {days} days."
            
            result = f"📅 *Events for the next {days} days*\n\n"
            
            for event in events:
                summary = event.get('summary', 'No Title')
                start = event.get('start', {})
                end = event.get('end', {})
                
                # Format start time
                if 'dateTime' in start:
                    start_time = datetime.fromisoformat(start['dateTime'].replace('Z', '+00:00'))
                    start_str = start_time.strftime('%Y-%m-%d %H:%M')
                elif 'date' in start:
                    start_str = start['date']
                else:
                    start_str = "Unknown"
                
                # Format end time
                if 'dateTime' in end:
                    end_time = datetime.fromisoformat(end['dateTime'].replace('Z', '+00:00'))
                    end_str = end_time.strftime('%H:%M')
                elif 'date' in end:
                    end_str = "All day"
                else:
                    end_str = "Unknown"
                
                result += f"📅 *{summary}*\n"
                result += f"   📆 {start_str}"
                if end_str != "All day":
                    result += f" - {end_str}"
                result += f"\n"
                
                if event.get('location'):
                    result += f"   📍 {event['location']}\n"
                
                if event.get('attendees'):
                    attendee_count = len(event['attendees'])
                    result += f"   👥 {attendee_count} attendee(s)\n"
                
                result += "\n"
            
            return result
            
        except Exception as e:
            logger.error(f"Error listing events: {e}")
            return f"❌ Error listing events: {str(e)}"
    
    async def create_event(self, summary: str, start_time: str, end_time: str = None, 
                          description: str = "", location: str = "", 
                          attendees: List[str] = None, calendar_id: str = 'primary') -> str:
        """Create a new calendar event"""
        try:
            # If no end time provided, make it 1 hour after start
            if not end_time:
                start_dt = datetime.fromisoformat(start_time.replace('Z', '+00:00'))
                end_dt = start_dt + timedelta(hours=1)
                end_time = end_dt.isoformat()
            
            event = self.calendar_api.create_event(
                calendar_id=calendar_id,
                summary=summary,
                description=description,
                start_time=start_time,
                end_time=end_time,
                attendees=attendees,
                location=location
            )
            
            if isinstance(event, dict) and "error" in event:
                return f"❌ Error creating event: {event['error']}"
            
            result = f"✅ *Event Created Successfully*\n\n"
            result += f"📅 *{event.get('summary', 'No Title')}*\n"
            result += f"📆 Start: {event.get('start', {}).get('dateTime', 'Unknown')}\n"
            result += f"📆 End: {event.get('end', {}).get('dateTime', 'Unknown')}\n"
            
            if event.get('location'):
                result += f"📍 {event['location']}\n"
            
            if event.get('attendees'):
                result += f"👥 Attendees: {len(event['attendees'])}\n"
            
            result += f"\n🔗 [View Event]({event.get('htmlLink', '#')})"
            
            return result
            
        except Exception as e:
            logger.error(f"Error creating event: {e}")
            return f"❌ Error creating event: {str(e)}"
    
    async def delete_event(self, event_id: str, calendar_id: str = 'primary') -> str:
        """Delete a calendar event"""
        try:
            result = self.calendar_api.delete_event(calendar_id, event_id)
            
            if isinstance(result, dict) and "error" in result:
                return f"❌ Error deleting event: {result['error']}"
            
            return "✅ Event deleted successfully"
            
        except Exception as e:
            logger.error(f"Error deleting event: {e}")
            return f"❌ Error deleting event: {str(e)}"
    
    async def get_availability(self, calendar_id: str = 'primary', days: int = 1) -> str:
        """Get availability for a calendar"""
        try:
            # Calculate time range
            now = datetime.utcnow()
            time_min = now.isoformat() + 'Z'
            time_max = (now + timedelta(days=days)).isoformat() + 'Z'
            
            free_busy = self.calendar_api.get_free_busy(
                calendar_ids=[calendar_id],
                time_min=time_min,
                time_max=time_max
            )
            
            if isinstance(free_busy, dict) and "error" in free_busy:
                return f"❌ Error getting availability: {free_busy['error']}"
            
            calendars = free_busy.get('calendars', {})
            calendar_data = calendars.get(calendar_id, {})
            busy_times = calendar_data.get('busy', [])
            
            if not busy_times:
                return f"✅ You are available for the next {days} day(s)"
            
            result = f"📅 *Availability for the next {days} day(s)*\n\n"
            result += "🚫 *Busy Times:*\n\n"
            
            for busy in busy_times:
                start = datetime.fromisoformat(busy['start'].replace('Z', '+00:00'))
                end = datetime.fromisoformat(busy['end'].replace('Z', '+00:00'))
                
                start_str = start.strftime('%Y-%m-%d %H:%M')
                end_str = end.strftime('%H:%M')
                
                result += f"📆 {start_str} - {end_str}\n"
            
            result += f"\n✅ You are available outside of these times."
            
            return result
            
        except Exception as e:
            logger.error(f"Error getting availability: {e}")
            return f"❌ Error getting availability: {str(e)}"
    
    async def search_events(self, query: str, calendar_id: str = 'primary', max_results: int = 10) -> str:
        """Search for events"""
        try:
            events = self.calendar_api.search_events(
                calendar_id=calendar_id,
                query=query,
                max_results=max_results
            )
            
            if isinstance(events, dict) and "error" in events:
                return f"❌ Error searching events: {events['error']}"
            
            if not events:
                return f"🔍 No events found matching '{query}'"
            
            result = f"🔍 *Search Results for '{query}'*\n\n"
            
            for event in events:
                summary = event.get('summary', 'No Title')
                start = event.get('start', {})
                
                # Format start time
                if 'dateTime' in start:
                    start_time = datetime.fromisoformat(start['dateTime'].replace('Z', '+00:00'))
                    start_str = start_time.strftime('%Y-%m-%d %H:%M')
                elif 'date' in start:
                    start_str = start['date']
                else:
                    start_str = "Unknown"
                
                result += f"📅 *{summary}*\n"
                result += f"   📆 {start_str}\n"
                
                if event.get('location'):
                    result += f"   📍 {event['location']}\n"
                
                result += "\n"
            
            return result
            
        except Exception as e:
            logger.error(f"Error searching events: {e}")
            return f"❌ Error searching events: {str(e)}"
    
    def parse_datetime(self, date_str: str) -> Optional[str]:
        """Parse various date/time formats"""
        try:
            # Handle common formats
            formats = [
                '%Y-%m-%d %H:%M',
                '%Y-%m-%d %H:%M:%S',
                '%Y-%m-%d',
                '%m/%d/%Y %H:%M',
                '%m/%d/%Y',
                '%d/%m/%Y %H:%M',
                '%d/%m/%Y'
            ]
            
            for fmt in formats:
                try:
                    dt = datetime.strptime(date_str, fmt)
                    return dt.isoformat()
                except ValueError:
                    continue
            
            return None
        except Exception:
            return None 