import sys
import os
import subprocess
from app import create_app, db
from app.models import Folder, User, ProcessedEmail
from app.imap_service import IMAPService
from app.processed_emails_service import ProcessedEmailsService
from flask.cli import with_appcontext
import click

app = create_app()

@app.cli.command()
@with_appcontext
def shell():
    """Run a shell in the app context."""
    import code
    code.interact(local=dict(globals(), **locals()))

@app.cli.command("setup-dev")
def setup_dev():
    """Set up development environment with Docker Compose."""
    # Create tmp directory for IMAP data if it doesn't exist
    os.makedirs('tmp/imap-data', exist_ok=True)
    
    # Start the services
    try:
        subprocess.run(['docker-compose', 'up', '-d'], check=True)
        print("Services started successfully:")
        print("- PostgreSQL: localhost:5432 (database: email_organizer_dev, user: postgres, password: password)")
        print("- IMAP Server: localhost:1143")
        print("  Users:")
        print("    - user1@example.com / password1")
        print("    - user2@example.com / password2")
        print("  Folders: INBOX, Pending, Work, Personal, Receipts, Marketing, Archived")
    except subprocess.CalledProcessError as e:
        print(f"Error starting services: {e}")
        sys.exit(1)
    except FileNotFoundError:
        print("Docker Compose not found. Please install Docker and Docker Compose.")
        sys.exit(1)

def mock_process_emails():
    """Simulate processing emails with defined rules."""
    with app.app_context():
        # Mock user ID
        mock_user_id = '123e4567-e89b-12d3-a456-426614174000'
        folders = Folder.query.filter_by(user_id=mock_user_id).all()
        
        # Mock emails
        emails = [
            {'subject': 'Your Amazon Order', 'from': 'no-reply@amazon.com', 'body': 'Your order has shipped.'},
            {'subject': 'Meeting Reminder', 'from': 'boss@company.com', 'body': 'Don\'t forget the meeting at 3 PM.'},
            {'subject': 'Special Offer!', 'from': 'deals@shop.com', 'body': 'Exclusive discounts inside!'}
        ]
        
        print("Starting mock email processing...")
        for email in emails:
            print(f"\nProcessing email: {email['subject']}")
            matched = False
            for folder in folders:
                # Simple mock rule matching (in real app, this would be more complex)
                if folder.rule_text.lower() in email['subject'].lower() or folder.rule_text.lower() in email['from'].lower():
                    print(f"  -> Matched rule '{folder.rule_text}' -> Folder '{folder.name}'")
                    matched = True
                    break
            if not matched:
                print("  -> No matching rule found.")


@app.cli.command("process-pending-emails")
@click.option("--user-id", help="Process emails for a specific user ID only")
@click.option("--folder-name", help="Process emails for a specific folder only")
@click.option("--batch-size", default=100, help="Number of emails to process in each batch")
@click.option("--dry-run", is_flag=True, help="Show what would be processed without actually processing")
@with_appcontext
def process_pending_emails(user_id, folder_name, batch_size, dry_run):
    """Process pending emails for all users or specific user/folder."""
    from app.processed_emails_service import ProcessedEmailsService
    
    with app.app_context():
        # Build query for users
        user_query = User.query
        if user_id:
            user_query = user_query.filter_by(id=int(user_id))
        
        users = user_query.all()
        if not users:
            print("No users found to process")
            return
        
        total_processed = 0
        total_users = len(users)
        
        print(f"Starting email processing for {total_users} user(s)...")
        
        for i, user in enumerate(users, 1):
            print(f"\nProcessing user {i}/{total_users}: {user.email}")
            
            # Skip users without IMAP configuration
            if not user.imap_config:
                print("  - Skipping: No IMAP configuration")
                continue
            
            try:
                # Initialize services
                imap_service = IMAPService(user)
                processed_emails_service = ProcessedEmailsService(user)
                
                # Get folders for this user
                folders = Folder.query.filter_by(user_id=user.id).all()
                
                if not folders:
                    print("  - No folders found for this user")
                    continue
                
                # Process each folder
                for folder in folders:
                    # Skip if specific folder name is specified and doesn't match
                    if folder_name and folder.name != folder_name:
                        continue
                    
                    print(f"  - Processing folder: {folder.name}")
                    
                    # Get all pending emails for this folder
                    pending_emails = ProcessedEmail.query.filter_by(
                        user_id=user.id,
                        folder_name=folder.name,
                        is_processed=False
                    ).all()
                    
                    if not pending_emails:
                        print(f"    - No pending emails in this folder")
                        continue
                    
                    total_pending = len(pending_emails)
                    print(f"    - Found {total_pending} pending emails")
                    
                    # Process in batches
                    processed_in_folder = 0
                    for j in range(0, total_pending, batch_size):
                        batch = pending_emails[j:j + batch_size]
                        batch_uids = [email.email_uid for email in batch]
                        
                        if dry_run:
                            print(f"    - Dry run: Would process {len(batch_uids)} emails")
                            processed_in_folder += len(batch_uids)
                        else:
                            # Mark emails as processed
                            result = processed_emails_service.mark_emails_processed(
                                folder_name=folder.name,
                                email_uids=batch_uids
                            )
                            processed_in_folder += result
                            print(f"    - Processed {result} emails in this batch")
                        
                        # Commit after each batch to avoid large transactions
                        db.session.commit()
                    
                    print(f"    - Total processed in folder: {processed_in_folder}/{total_pending}")
                    total_processed += processed_in_folder
            
            except Exception as e:
                print(f"  - Error processing user {user.email}: {str(e)}")
                import traceback
                traceback.print_exc()
                db.session.rollback()
                continue
        
        if not dry_run:
            print(f"\nCompleted! Total emails processed: {total_processed}")
        else:
            print(f"\nDry run completed! Total emails would be processed: {total_processed}")

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'mock-process':
        mock_process_emails()
    else:
        print("Usage: python manage.py mock-process")
        print("       flask setup-dev")
