import logging
import time
from datetime import datetime, timedelta
from threading import Thread
from app.models import User
from app.email_processor import EmailProcessor
from app import create_app

class Scheduler:
    """
    Background scheduler for email processing tasks.
    Runs as a separate thread to process emails at regular intervals.
    """
    
    def __init__(self, app=None, interval_minutes=5):
        self.app = app
        self.interval = interval_minutes * 60  # Convert to seconds
        self.thread = None
        self.running = False
        self.logger = logging.getLogger(__name__)
        
        if app:
            self.init_app(app)
    
    def init_app(self, app):
        """Initialize the scheduler with a Flask application."""
        self.app = app
        
        # Store scheduler in app extensions
        if not hasattr(app, 'extensions'):
            app.extensions = {}
        app.extensions['scheduler'] = self
    
    def start(self):
        """Start the background scheduler thread."""
        if self.running:
            self.logger.warning("Scheduler is already running")
            return
            
        self.running = True
        self.thread = Thread(target=self._run, daemon=True)
        self.thread.start()
        self.logger.info(f"Scheduler started with {self.interval//60} minute interval")
    
    def stop(self):
        """Stop the background scheduler."""
        self.running = False
        if self.thread:
            self.logger.info("Scheduler stopped")
            self.thread.join()
    
    def _run(self):
        """Main loop for the scheduler."""
        # Wait a moment before first run to allow app to start
        time.sleep(5)
        
        while self.running:
            try:
                self.logger.info("Starting scheduled email processing")
                self.process_all_users()
                
                # Calculate next run time
                next_run = datetime.now() + timedelta(seconds=self.interval)
                self.logger.info(f"Next run at {next_run.strftime('%Y-%m-%d %H:%M:%S')}")
                
                # Sleep for the interval, checking every 10 seconds if we should stop
                slept = 0
                while self.running and slept < self.interval:
                    sleep_time = min(10, self.interval - slept)
                    time.sleep(sleep_time)
                    slept += sleep_time
                    
            except Exception as e:
                self.logger.error(f"Error in scheduler: {str(e)}")
                # Continue running even if there's an error
                continue
    
    def process_all_users(self):
        """Process emails for all users."""
        with self.app.app_context():
            try:
                # Get all users
                users = User.query.all()
                
                if not users:
                    self.logger.info("No users found for processing")
                    return
                
                self.logger.info(f"Processing emails for {len(users)} users")
                
                # Process each user's emails
                for user in users:
                    try:
                        processor = EmailProcessor(user)
                        result = processor.process_user_emails()
                        
                        self.logger.info(f"Completed processing for user {user.email}: "
                                      f"{result['success_count']} success, "
                                      f"{result['error_count']} errors, "
                                      f"{len(result['processed_folders'])} folders processed")
                        
                    except Exception as e:
                        self.logger.error(f"Error processing emails for user {user.email}: {str(e)}")
                        continue
                        
            except Exception as e:
                self.logger.error(f"Error in process_all_users: {str(e)}")