import requests
from msal import ConfidentialClientApplication, PublicClientApplication
import re
from typing import List, Dict, Optional
from html.parser import HTMLParser
from html import unescape
import logging
from datetime import datetime, timezone
import os
import base64
import json

class HTMLTextExtractor(HTMLParser):
    """Extract text from HTML content"""
    def __init__(self):
        super().__init__()
        self.text = []
        self.current_tag = None
    
    def handle_starttag(self, tag, attrs):
        self.current_tag = tag
        if tag == 'br':
            self.text.append('\n')
    
    def handle_endtag(self, tag):
        if tag in ['p', 'div', 'tr', 'li']:
            self.text.append('\n')
        self.current_tag = None
    
    def handle_data(self, data):
        self.text.append(data)
    
    def get_text(self):
        return ''.join(self.text).strip()


def setup_logging(log_file: str = "email_checker.log"):
    """
    Set up logging configuration
    Logs to both file and console
    """
    # Create logs directory if it doesn't exist
    log_dir = "logs"
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    
    log_path = os.path.join(log_dir, log_file)
    
    # Configure logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
        handlers=[
            logging.FileHandler(log_path),
            logging.StreamHandler()  # Also log to console
        ]
    )
    
    logger = logging.getLogger(__name__)
    logger.info("="*60)
    logger.info("Email Checker Script Started (Microsoft Graph API)")
    logger.info(f"Log file: {log_path}")
    logger.info("="*60)
    return logger


class EmailChecker:
    def __init__(self, email_address: str, client_id: str, client_secret: str, 
                 tenant_id: str, authority: Optional[str] = None):
        """
        Initialize email checker using Microsoft Graph API
        
        Args:
            email_address: Your email address (user principal name)
            client_id: Azure AD Application (Client) ID
            client_secret: Azure AD Application Client Secret (the VALUE, not the Secret ID!)
            tenant_id: Azure AD Tenant ID (or 'common' for multi-tenant)
            authority: Optional custom authority URL (defaults to https://login.microsoftonline.com/{tenant_id})
        """
        self.email_address = email_address
        self.client_id = client_id
        self.client_secret = client_secret
        self.tenant_id = tenant_id
        self.authority = authority or f"https://login.microsoftonline.com/{tenant_id}"
        self.graph_endpoint = "https://graph.microsoft.com/v1.0"
        self.access_token = None
        self.logger = logging.getLogger(__name__)
        self.scope = ["https://graph.microsoft.com/.default"]
        
        # Validate client secret format (basic check)
        if client_secret and len(client_secret) == 36 and client_secret.count('-') == 4:
            self.logger.warning("⚠️  WARNING: Your CLIENT_SECRET looks like a Secret ID (UUID format) instead of a Secret Value!")
            self.logger.warning("   Secret IDs look like: '46804c3d-9b84-40b4-8972-d0b493ffa4d1'")
            self.logger.warning("   Secret Values look like: '0eB8Q~zpWLgBaBjbuSEdCcWw0PqebXY...' (long random string)")
            self.logger.warning("   Please use the Secret VALUE, not the Secret ID!")
            self.logger.warning("   See GET_SECRET.md for instructions on how to get the correct value.")
        elif client_secret in ["YOUR_SECRET_VALUE_HERE", "", None]:
            self.logger.error("❌ ERROR: CLIENT_SECRET is not set! Please update fetch.py with your actual secret value.")
            self.logger.error("   See GET_SECRET.md for instructions.")
    
    def get_access_token(self):
        """Get access token using client credentials flow"""
        self.logger.info("Attempting to authenticate with Microsoft Graph API...")
        self.logger.info(f"Authority: {self.authority}")
        self.logger.info(f"Client ID: {self.client_id}")
        self.logger.info("Creating ConfidentialClientApplication...")
        
        try:
            # Create a confidential client application with timeout
            app = ConfidentialClientApplication(
                client_id=self.client_id,
                client_credential=self.client_secret,
                authority=self.authority,
                timeout=30  # 30 second timeout for requests
            )
            self.logger.info("ConfidentialClientApplication created successfully")
            
            # Acquire token for client credentials flow
            self.logger.info("Calling acquire_token_for_client...")
            self.logger.info(f"Scopes: {self.scope}")
            result = app.acquire_token_for_client(scopes=self.scope)
            self.logger.info("acquire_token_for_client call completed")
            
            if "access_token" in result:
                self.access_token = result["access_token"]
                self.logger.info("Successfully obtained access token")
                return True
            else:
                error = result.get("error_description", result.get("error", "Unknown error"))
                error_code = result.get("error_codes", [])
                self.logger.error(f"Failed to obtain access token: {error}")
                self.logger.error(f"Error code: {error_code}")
                self.logger.error(f"Full error details: {result}")
                
                # Provide helpful error messages
                if "AADSTS7000215" in str(result) or "invalid_client_secret" in str(error).lower():
                    self.logger.error("Invalid client secret. Please verify your CLIENT_SECRET.")
                elif "AADSTS700016" in str(result) or "invalid_client" in str(error).lower():
                    self.logger.error("Invalid client ID. Please verify your CLIENT_ID.")
                elif "AADSTS90002" in str(result):
                    self.logger.error("Invalid tenant ID. Please verify your TENANT_ID.")
                elif "AADSTS65005" in str(result):
                    self.logger.error("Application does not have required permissions. Please grant Mail.Read permission and admin consent.")
                
                return False
                
        except requests.exceptions.Timeout as e:
            self.logger.error(f"Timeout during authentication: {e}")
            self.logger.error("The authentication request timed out. Please check your network connection.")
            return False
        except requests.exceptions.ConnectionError as e:
            self.logger.error(f"Connection error during authentication: {e}")
            self.logger.error("Could not connect to Microsoft authentication service. Please check your network connection.")
            return False
        except Exception as e:
            self.logger.error(f"Error during authentication: {e}", exc_info=True)
            return False
    
    def get_access_token_with_password(self, username: str, password: str):
        """
        Alternative: Get access token using Resource Owner Password Credentials (ROPC) flow
        Note: This requires username and password, and may not work if MFA is enabled
        """
        self.logger.info("Attempting to authenticate with username/password...")
        self.logger.info(f"Authority: {self.authority}")
        self.logger.info(f"Client ID: {self.client_id}")
        
        try:
            # Create a public client application for ROPC flow
            app = PublicClientApplication(
                client_id=self.client_id,
                authority=self.authority
            )
            
            # Acquire token using username and password
            result = app.acquire_token_by_username_password(
                username=username,
                password=password,
                scopes=["https://graph.microsoft.com/Mail.Read"]
            )
            
            if "access_token" in result:
                self.access_token = result["access_token"]
                self.logger.info("Successfully obtained access token")
                return True
            else:
                error = result.get("error_description", result.get("error", "Unknown error"))
                self.logger.error(f"Failed to obtain access token: {error}")
                self.logger.error(f"Error details: {result}")
                if "AADSTS50076" in str(result) or "MFA" in str(result):
                    self.logger.error("Multi-factor authentication is required. Please use client credentials flow instead.")
                return False
                
        except Exception as e:
            self.logger.error(f"Error during authentication: {e}", exc_info=True)
            return False
    
    def connect(self, use_password: bool = False, password: Optional[str] = None):
        """
        Connect to Microsoft Graph API
        
        Args:
            use_password: If True, use username/password flow. If False, use client credentials flow.
            password: Required if use_password is True
        """
        if use_password:
            if not password:
                self.logger.error("Password is required when using password authentication")
                return False
            return self.get_access_token_with_password(self.email_address, password)
        else:
            return self.get_access_token()
    
    def make_graph_request(self, endpoint: str, method: str = "GET", params: Optional[Dict] = None, retry_on_401: bool = True):
        """
        Make a request to Microsoft Graph API
        
        Args:
            endpoint: Graph API endpoint (e.g., "/users/{email}/messages")
            method: HTTP method (GET, POST, etc.)
            params: Query parameters
            retry_on_401: If True, automatically re-authenticate and retry on 401 errors
        """
        if not self.access_token:
            self.logger.error("No access token available. Call connect() first.")
            return None
        
        url = f"{self.graph_endpoint}{endpoint}"
        headers = {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json"
        }
        
        try:
            if method == "GET":
                response = requests.get(url, headers=headers, params=params)
            elif method == "POST":
                response = requests.post(url, headers=headers, json=params)
            else:
                self.logger.error(f"Unsupported HTTP method: {method}")
                return None
            
            response.raise_for_status()
            return response.json()
            
        except requests.exceptions.HTTPError as e:
            # Check if it's a 401 Unauthorized error (expired token)
            if e.response.status_code == 401 and retry_on_401:
                self.logger.warning("Received 401 Unauthorized - token may be expired. Attempting to re-authenticate...")
                # Try to re-authenticate
                if self.connect():
                    self.logger.info("Re-authentication successful. Retrying request...")
                    # Retry the request with new token
                    headers["Authorization"] = f"Bearer {self.access_token}"
                    try:
                        if method == "GET":
                            response = requests.get(url, headers=headers, params=params)
                        elif method == "POST":
                            response = requests.post(url, headers=headers, json=params)
                        response.raise_for_status()
                        return response.json()
                    except requests.exceptions.HTTPError as retry_e:
                        self.logger.error(f"HTTP error on retry: {retry_e}")
                        if hasattr(retry_e.response, 'text'):
                            self.logger.error(f"Response: {retry_e.response.text}")
                        return None
                    except Exception as retry_e:
                        self.logger.error(f"Error on retry: {retry_e}", exc_info=True)
                        return None
                else:
                    self.logger.error("Re-authentication failed. Cannot retry request.")
                    if hasattr(e.response, 'text'):
                        self.logger.error(f"Response: {e.response.text}")
                    return None
            else:
                self.logger.error(f"HTTP error: {e}")
                if hasattr(e.response, 'text'):
                    self.logger.error(f"Response: {e.response.text}")
                return None
        except Exception as e:
            self.logger.error(f"Error making Graph API request: {e}", exc_info=True)
            return None
    
    def get_email_body(self, email_data: Dict) -> str:
        """Extract email body from Graph API email data"""
        body_text = ""
        
        # Graph API provides body in different formats
        body_content = email_data.get("body", {})
        
        # Debug: Log what we're getting
        if not body_content:
            self.logger.warning("No 'body' field in email data. Keys available: " + str(list(email_data.keys())))
            # Try to fetch the full message if body is not included
            return ""
        
        body_type = body_content.get("contentType", "text")
        body_value = body_content.get("content", "")
        
        if not body_value:
            self.logger.warning(f"Body content is empty. Body structure: {body_content}")
        
        if body_type == "html":
            # Extract text from HTML
            parser = HTMLTextExtractor()
            parser.feed(body_value)
            body_text = parser.get_text()
        else:
            body_text = body_value
        
        return body_text.strip()
    
    def extract_email_details(self, body: str) -> Dict[str, any]:
        """
        Extract booking details from email body based on Twine email format
        Extracts: Name, Phone, Email, Address, Date & Time, Drop Off Location, 
        Number of Passengers, Pick Up Location
        """
        details = {
            'name': None,
            'phone': None,
            'email': None,
            'address': None,
            'date_time': None,
            'date': None,
            'time': None,
            'drop_off_location': None,
            'number_of_passengers': None,
            'pick_up_location': None,
            'raw_body': body
        }
        
        # The email format has labels directly followed by values (no colon, no space)
        # Pattern: "LabelValue" - e.g., "NameTay Tay", "Phone(323) 359-6264"
        # Format example:
        # NameTay Tay
        # Phone(323) 359-6264
        # Emailt-zaidan@live.com
        # Address4018 Buckingham Road, Los Angeles, CA, 90008
        # Date & Time2025-11-20 4:10 AM
        # Drop Off Location300 S Main St Los Angeles CA 90013
        # Number of Passengers1
        # Pick Up Location4018 Buckingham Rd Los Angeles CA 90008
        
        # Extract Name - format: "NameTay Tay" (label directly followed by value, then newline)
        name_match = re.search(r'Name([^\n]+)', body, re.IGNORECASE)
        if name_match:
            details['name'] = name_match.group(1).strip()
            self.logger.debug(f"Extracted Name: {details['name']}")
        else:
            self.logger.warning("Could not extract Name from email body")
        
        # Extract Phone - format: "Phone(323) 359-6264"
        phone_match = re.search(r'Phone([^\n]+)', body, re.IGNORECASE)
        if phone_match:
            details['phone'] = phone_match.group(1).strip()
            self.logger.debug(f"Extracted Phone: {details['phone']}")
        else:
            self.logger.warning("Could not extract Phone from email body")
        
        # Extract Email - format: "Emailt-zaidan@live.com"
        email_match = re.search(r'Email([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,})', body, re.IGNORECASE)
        if email_match:
            details['email'] = email_match.group(1).strip()
            self.logger.debug(f"Extracted Email: {details['email']}")
        else:
            self.logger.warning("Could not extract Email from email body")
        
        # Extract Address - format: "Address4018 Buckingham Road, Los Angeles, CA, 90008"
        address_match = re.search(r'Address([^\n]+)', body, re.IGNORECASE)
        if address_match:
            address = address_match.group(1).strip()
            # Clean up - remove extra whitespace and newlines
            address = re.sub(r'\s+', ' ', address)
            details['address'] = address
            self.logger.debug(f"Extracted Address: {details['address']}")
        else:
            self.logger.warning("Could not extract Address from email body")
        
        # Extract Date & Time - format: "Date & Time2025-11-20 4:10 AM"
        datetime_match = re.search(r'Date\s*[&\s]*Time([^\n]+)', body, re.IGNORECASE)
        if datetime_match:
            date_time = datetime_match.group(1).strip()
            # Skip if it's [Unknown]
            if date_time.lower() != "[unknown]":
                details['date_time'] = date_time
                self.logger.debug(f"Extracted Date & Time: {details['date_time']}")
                # Also try to split into date and time
                # Format: "2025-11-20 4:10 AM"
                dt_split = re.match(r'(\d{4}-\d{2}-\d{2})\s+(.+)', date_time)
                if dt_split:
                    details['date'] = dt_split.group(1)
                    details['time'] = dt_split.group(2).strip()
                    self.logger.debug(f"Split into Date: {details['date']}, Time: {details['time']}")
        else:
            self.logger.warning("Could not extract Date & Time from email body")
        
        # Extract Drop Off Location - format: "Drop Off Location300 S Main St Los Angeles CA 90013"
        dropoff_match = re.search(r'Drop\s*[-\s]*Off\s*Location([^\n]+)', body, re.IGNORECASE)
        if dropoff_match:
            dropoff = dropoff_match.group(1).strip()
            # Skip if it's [Unknown]
            if dropoff.lower() != "[unknown]":
                details['drop_off_location'] = dropoff
                self.logger.debug(f"Extracted Drop Off Location: {details['drop_off_location']}")
        else:
            self.logger.warning("Could not extract Drop Off Location from email body")
        
        # Extract Number of Passengers - format: "Number of Passengers1"
        passenger_match = re.search(r'Number\s+of\s+Passengers?([^\n\d]*\d+)', body, re.IGNORECASE)
        if passenger_match:
            # Extract just the number
            number_match = re.search(r'(\d+)', passenger_match.group(1))
            if number_match:
                details['number_of_passengers'] = number_match.group(1).strip()
                self.logger.debug(f"Extracted Number of Passengers: {details['number_of_passengers']}")
        else:
            self.logger.warning("Could not extract Number of Passengers from email body")
        
        # Extract Pick Up Location - format: "Pick Up Location4018 Buckingham Rd Los Angeles CA 90008"
        pickup_match = re.search(r'Pick\s*[-\s]*Up\s*Location([^\n]+)', body, re.IGNORECASE)
        if pickup_match:
            pickup = pickup_match.group(1).strip()
            # Skip if it's [Unknown]
            if pickup.lower() != "[unknown]":
                details['pick_up_location'] = pickup
                self.logger.debug(f"Extracted Pick Up Location: {details['pick_up_location']}")
        else:
            self.logger.warning("Could not extract Pick Up Location from email body")
        
        # Log extraction summary
        extracted_count = sum(1 for v in details.values() if v is not None and v != details['raw_body'])
        self.logger.info(f"Extracted {extracted_count} fields from email body")
        
        return details
    
    def check_emails_from_sender(self, sender_email: str = "scheduling@usetwine.com", 
                                 folder: str = "inbox", unread_only: bool = False, 
                                 top: int = 100, from_date: Optional[str] = None) -> List[Dict]:
        """
        Check emails from a specific sender using Microsoft Graph API
        
        Args:
            sender_email: Email address to search for
            folder: Email folder to search (default: inbox)
            unread_only: If True, only check unread emails
            top: Maximum number of emails to retrieve (default: 100)
            from_date: Filter emails from this date onwards (format: "YYYY-MM-DD" or "YYYY-MM-DDTHH:MM:SSZ")
                      Example: "2025-12-16" or "2025-12-16T00:00:00Z"
        
        Returns:
            List of dictionaries containing email details
        """
        if not self.access_token:
            self.logger.error("Not authenticated. Call connect() first.")
            return []
        
        try:
            # Build the filter query - simplified to avoid Graph API limitations
            # We'll filter by sender in Python after fetching (Graph API doesn't support
            # complex filters combining nested properties like from/emailAddress/address with dates)
            filter_parts = []
            from_date_iso = None
            
            # Only add date filter to Graph API query (simpler filter)
            if from_date:
                # Convert date to ISO 8601 format if needed
                if len(from_date) == 10:  # Format: YYYY-MM-DD
                    from_date_iso = f"{from_date}T00:00:00Z"
                else:
                    from_date_iso = from_date
                    # Ensure it ends with Z if it's a full datetime
                    if not from_date_iso.endswith('Z') and '+' not in from_date_iso:
                        from_date_iso = from_date_iso + 'Z'
                
                # Graph API filter syntax: receivedDateTime ge {datetime}
                filter_parts.append(f"receivedDateTime ge {from_date_iso}")
                self.logger.info(f"Filtering emails from {from_date} onwards (ISO: {from_date_iso})")
            
            # Add unread filter if needed
            if unread_only:
                filter_parts.append("isRead eq false")
            
            # Combine filter parts
            filter_query = " and ".join(filter_parts) if filter_parts else None
            
            # Graph API endpoint for user's messages
            endpoint = f"/users/{self.email_address}/mailFolders/{folder}/messages"
            
            params = {
                "$top": top,
                "$select": "id,subject,from,receivedDateTime,body,isRead",
                "$orderby": "receivedDateTime desc"
            }
            
            # Only add filter if we have one
            if filter_query:
                params["$filter"] = filter_query
            
            self.logger.info(f"Searching for emails in folder {folder}")
            if from_date:
                self.logger.info(f"Date filter: from {from_date} onwards")
            if unread_only:
                self.logger.info("Filtering for UNREAD emails only")
            self.logger.info(f"Will filter by sender '{sender_email}' in Python after fetching")
            
            # Make the request
            response_data = self.make_graph_request(endpoint, params=params)
            
            if not response_data:
                self.logger.error("Failed to retrieve emails from Graph API")
                return []
            
            emails_data = response_data.get("value", [])
            self.logger.info(f"Retrieved {len(emails_data)} email(s) from Graph API")
            
            if from_date_iso:
                self.logger.info(f"Python-side date filter will be applied: emails must be >= {from_date_iso}")
            
            # Filter by sender in Python (since Graph API doesn't support complex filters)
            emails_found = []
            filtered_by_date_count = 0
            filtered_by_sender_count = 0
            for email_data in emails_data:
                from_info = email_data.get("from", {})
                from_addr = from_info.get("emailAddress", {}).get("address", "").lower()
                
                # Filter by sender
                if from_addr != sender_email.lower():
                    filtered_by_sender_count += 1
                    continue
                
                # Additional date check in Python (in case Graph API filter didn't work perfectly)
                if from_date and from_date_iso:
                    received_date = email_data.get("receivedDateTime", "")
                    if received_date:
                        try:
                            # Parse the date from ISO format
                            # Handle both 'Z' and '+00:00' timezone formats
                            email_date_str = received_date.replace('Z', '+00:00')
                            filter_date_str = from_date_iso.replace('Z', '+00:00')
                            
                            email_date = datetime.fromisoformat(email_date_str)
                            filter_date = datetime.fromisoformat(filter_date_str)
                            
                            # Make both timezone-aware (UTC)
                            if email_date.tzinfo is None:
                                email_date = email_date.replace(tzinfo=timezone.utc)
                            if filter_date.tzinfo is None:
                                filter_date = filter_date.replace(tzinfo=timezone.utc)
                            
                            # Filter: only include emails received on or after the filter date
                            if email_date < filter_date:
                                filtered_by_date_count += 1
                                self.logger.debug(f"Filtering out email from {email_date} (before {filter_date})")
                                continue
                        except Exception as e:
                            self.logger.warning(f"Could not parse date {received_date}: {e}. Skipping email.")
                            continue  # Skip emails with unparseable dates when filtering by date
                    else:
                        # If we're filtering by date but email has no receivedDateTime, skip it
                        self.logger.warning("Email has no receivedDateTime but date filter is active. Skipping email.")
                        continue
                
                emails_found.append(email_data)
            
            self.logger.info(f"Found {len(emails_found)} email(s) from {sender_email} after filtering")
            if filtered_by_sender_count > 0:
                self.logger.info(f"Filtered out {filtered_by_sender_count} email(s) by sender")
            if filtered_by_date_count > 0:
                self.logger.info(f"Filtered out {filtered_by_date_count} email(s) by date")
            
            # Process the filtered emails
            processed_emails = []
            for idx, email_data in enumerate(emails_found, 1):
                email_id = email_data.get("id", "unknown")
                self.logger.info(f"Processing email {idx}/{len(emails_found)} (ID: {email_id})")
                
                # Extract email information
                subject = email_data.get("subject", "No Subject")
                from_info = email_data.get("from", {})
                from_addr = from_info.get("emailAddress", {}).get("address", "Unknown")
                from_name = from_info.get("emailAddress", {}).get("name", "")
                date = email_data.get("receivedDateTime", "")
                
                self.logger.info(f"Email Subject: {subject}")
                self.logger.info(f"Email From: {from_name} <{from_addr}>")
                self.logger.info(f"Email Date: {date}")
                
                # Fetch full email body (Graph API may truncate body in list requests)
                # Get the full message to ensure we have the complete body
                try:
                    full_message = self.make_graph_request(
                        f"/users/{self.email_address}/messages/{email_id}",
                        params={"$select": "body"}
                    )
                    
                    # Use full message body if available, otherwise use the one from list
                    if full_message and full_message.get("body"):
                        email_data["body"] = full_message.get("body")
                        self.logger.debug("Fetched full message body")
                    else:
                        self.logger.warning("Could not fetch full message body, using body from list")
                except Exception as e:
                    self.logger.warning(f"Error fetching full message body: {e}, using body from list")
                
                # Get email body
                self.logger.debug("Extracting email body...")
                body = self.get_email_body(email_data)
                self.logger.debug(f"Email body length: {len(body)} characters")
                
                # Debug: Log first 500 characters of body to see the format
                if body:
                    self.logger.info(f"Email body preview (first 500 chars):\n{body[:500]}")
                else:
                    self.logger.warning("Email body is empty!")
                
                # Extract details from body
                self.logger.info("Extracting booking details from email body...")
                details = self.extract_email_details(body)
                
                email_info = {
                    'id': email_id,
                    'subject': subject,
                    'from': f"{from_name} <{from_addr}>" if from_name else from_addr,
                    'date': date,
                    'body': body,
                    'extracted_details': details
                }
                
                processed_emails.append(email_info)
                
                # Log and print summary
                self.logger.info("="*60)
                self.logger.info(f"Email ID: {email_id}")
                self.logger.info(f"Subject: {subject}")
                self.logger.info(f"From: {from_name} <{from_addr}>")
                self.logger.info(f"Date: {date}")
                self.logger.info("\nExtracted Booking Details:")
                self.logger.info(f"  Name: {details.get('name', 'N/A')}")
                self.logger.info(f"  Phone: {details.get('phone', 'N/A')}")
                self.logger.info(f"  Email: {details.get('email', 'N/A')}")
                self.logger.info(f"  Address: {details.get('address', 'N/A')}")
                if details.get('date_time'):
                    self.logger.info(f"  Date & Time: {details.get('date_time')}")
                else:
                    self.logger.info(f"  Date: {details.get('date', 'N/A')}")
                    self.logger.info(f"  Time: {details.get('time', 'N/A')}")
                self.logger.info(f"  Pick Up Location: {details.get('pick_up_location', 'N/A')}")
                self.logger.info(f"  Drop Off Location: {details.get('drop_off_location', 'N/A')}")
                self.logger.info(f"  Number of Passengers: {details.get('number_of_passengers', 'N/A')}")
                self.logger.info("="*60)
                
                # Also print to console for immediate visibility
                print(f"\n{'='*60}")
                print(f"Email ID: {email_id}")
                print(f"Subject: {subject}")
                print(f"From: {from_name} <{from_addr}>")
                print(f"Date: {date}")
                print(f"\nExtracted Booking Details:")
                print(f"  Name: {details.get('name', 'N/A')}")
                print(f"  Phone: {details.get('phone', 'N/A')}")
                print(f"  Email: {details.get('email', 'N/A')}")
                print(f"  Address: {details.get('address', 'N/A')}")
                if details.get('date_time'):
                    print(f"  Date & Time: {details.get('date_time')}")
                else:
                    print(f"  Date: {details.get('date', 'N/A')}")
                    print(f"  Time: {details.get('time', 'N/A')}")
                print(f"  Pick Up Location: {details.get('pick_up_location', 'N/A')}")
                print(f"  Drop Off Location: {details.get('drop_off_location', 'N/A')}")
                print(f"  Number of Passengers: {details.get('number_of_passengers', 'N/A')}")
                print(f"{'='*60}\n")
            
            self.logger.info(f"Successfully processed {len(processed_emails)} email(s)")
            return processed_emails
            
        except Exception as e:
            self.logger.error(f"Error checking emails: {e}", exc_info=True)
            return []


def main():
    """
    Main function - checks emails from scheduling@usetwine.com and extracts booking details
    """
    # Set up logging
    logger = setup_logging()
    
    # Microsoft Graph API Configuration
    # Replace these with your actual Azure AD app credentials
    EMAIL_ADDRESS = "info@troyrides.com"
    CLIENT_ID = "cc46473e-a7d7-4f74-8045-97f57672db79"  # Azure AD Application (Client) ID
    # IMPORTANT: CLIENT_SECRET must be the SECRET VALUE (starts with something like "0eB8Q~...")
    # NOT the Secret ID (which looks like "46804c3d-9b84-40b4-8972-d0b493ffa4d1")
    # Get it from: Azure Portal > App registrations > Your App > Certificates & secrets
    # If you don't have it, create a new client secret and copy the VALUE immediately
    CLIENT_SECRET = "0eB8Q~zpWLgBaBjbuSEdCcWw0PqebXYIZH8DMcfh"  # The actual secret value, not the Secret ID!
    TENANT_ID = "0b737fe7-8092-4deb-8adc-2c25370f9d55"  # Azure AD Tenant ID (or 'common' for multi-tenant)
    
    # Optional: If you want to use username/password instead of client credentials
    # Set USE_PASSWORD_AUTH to True and provide PASSWORD
    USE_PASSWORD_AUTH = False
    PASSWORD = None  # Only needed if USE_PASSWORD_AUTH is True
    
    logger.info("Initializing email checker with Microsoft Graph API...")
    logger.info(f"Email: {EMAIL_ADDRESS}")
    logger.info(f"Tenant ID: {TENANT_ID}")
    
    # Initialize email checker
    checker = EmailChecker(
        email_address=EMAIL_ADDRESS,
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET,
        tenant_id=TENANT_ID
    )
    
    # Connect to Microsoft Graph API
    if USE_PASSWORD_AUTH:
        if not checker.connect(use_password=True, password=PASSWORD):
            logger.error("Failed to authenticate with Microsoft Graph API using password.")
            logger.error("Please check your credentials or use client credentials flow instead.")
            return []
    else:
        if not checker.connect():
            logger.error("Failed to authenticate with Microsoft Graph API.")
            logger.error("Please check your Client ID, Client Secret, and Tenant ID.")
            return []
    
    try:
        # Check for emails from scheduling@usetwine.com
        # Only check emails from December 16, 2025 onwards
        logger.info("Starting email check process...")
        emails = checker.check_emails_from_sender(
            sender_email="scheduling@usetwine.com",
            folder="inbox",
            unread_only=False,  # Set to True to only check unread emails
            from_date="2025-12-17"  # Only fetch emails from December 16, 2025 onwards
        )
        
        logger.info("="*60)
        logger.info(f"Email check completed. Total emails found: {len(emails)}")
        logger.info("="*60)
        
        print(f"\n{'='*60}")
        print(f"Total emails found: {len(emails)}")
        print(f"{'='*60}\n")
        
        # Return the emails for further processing
        return emails
        
    except Exception as e:
        logger.error(f"Error processing emails: {e}", exc_info=True)
        return []


if __name__ == "__main__":
    main()
