from flask import Blueprint, render_template, request, jsonify, make_response
from flask_login import login_required, current_user
from app import db
from app.models import Folder
from app.imap_service import IMAPService
from app.processed_emails_service import ProcessedEmailsService
import logging

imap_bp = Blueprint('imap', __name__)

@imap_bp.route('/api/imap/config', methods=['GET'])
@login_required
def imap_config_modal():
    """Return the IMAP configuration modal."""
    # Pass existing IMAP config to the template if it exists
    response = make_response(render_template('partials/imap_config_modal.html',
                                           server=current_user.imap_config.get('server') if current_user.imap_config else None,
                                           port=current_user.imap_config.get('port') if current_user.imap_config else None,
                                           username=current_user.imap_config.get('username') if current_user.imap_config else None,
                                           password=current_user.imap_config.get('password') if current_user.imap_config else None,
                                           use_ssl=current_user.imap_config.get('use_ssl', True) if current_user.imap_config else True))
    response.headers['HX-Trigger'] = 'open-modal'
    return response

@imap_bp.route('/api/imap/folders/modal', methods=['GET'])
@login_required
def imap_folders_modal():
    """Return the folder selection modal after successful IMAP connection."""
    try:
        if not current_user.imap_config:
            return jsonify({'error': 'No IMAP configuration found. Please configure IMAP first.'}), 400
        
        # Test connection first
        imap_service = IMAPService(current_user)
        
        # Get folders from IMAP server
        imap_folders = imap_service.get_folders()
        
        if not imap_folders:
            return jsonify({'error': 'No folders found on IMAP server'}), 400
        
        # Get all existing folders in a single query
        existing_folders = Folder.query.filter(
            Folder.user_id == current_user.id
        ).all()
        
        # Create a dictionary for quick lookup
        existing_folders_dict = {folder.name: folder for folder in existing_folders}
        
        # Process folders
        unique_folders = []
        for imap_folder in imap_folders:
            folder_name = imap_folder['name'].strip()
            
            # Skip special folders that might not be needed
            if folder_name.lower() in ['sent', 'drafts', 'spam', 'trash']:
                continue
            
            # Check if this folder already exists in the database
            existing_folder = existing_folders_dict.get(folder_name)
            
            # Add folder type and subscribed status if it exists
            if existing_folder:
                imap_folder['folder_type'] = existing_folder.folder_type
                imap_folder['subscribed'] = True
                imap_folder['selected'] = True
            else:
                # Set default folder type
                imap_folder['folder_type'] = 'tidy' if folder_name.lower() == 'inbox' else 'destination'
                imap_folder['subscribed'] = False
                imap_folder['selected'] = True
            
            unique_folders.append(imap_folder)
        
        print(unique_folders, existing_folders_dict)
        # Return the folder selection modal
        response = make_response(render_template('partials/folder_selection_modal.html', folders=unique_folders))
        response.headers['hx-retarget'] = "#modal-holder"
        response.headers['HX-Trigger'] = 'open-modal'
        return response
            
    except Exception as e:
        logging.exception("Error getting IMAP folders modal: %s", e)
        print(e)
        return jsonify({'error': 'An unexpected error occurred while fetching folders'}), 500

@imap_bp.route('/api/imap/test', methods=['POST'])
@login_required
def test_imap_connection():
    """Test IMAP connection with provided configuration."""
    try:
        # Get form data
        server = request.form.get('server')
        port = request.form.get('port')
        username = request.form.get('username')
        password = request.form.get('password')
        use_ssl = request.form.get('use_ssl') == 'on'
        
        # Validate required fields
        errors = {}
        if not server:
            errors['server'] = 'Server is required'
        if not port:
            errors['port'] = 'Port is required'
        elif not port.isdigit():
            errors['port'] = 'Port must be a number'
        if not username:
            errors['username'] = 'Username is required'
        if not password:
            errors['password'] = 'Password is required'
        
        if errors:
            response = make_response(render_template('partials/imap_config_modal.html', errors=errors, server=server, port=port, username=username, use_ssl=use_ssl))
            response.headers['HX-Retarget'] = '#imap-modal'
            response.headers['HX-Reswap'] = 'outerHTML'
            return response
        
        # Store configuration temporarily for testing
        test_config = {
            'server': server,
            'port': int(port),
            'username': username,
            'password': password,
            'use_ssl': False,
            'use_tls': False,
            'connection_timeout': 30
        }
        
        # Test connection
        temp_user = type('User', (), {'imap_config': test_config})()
        imap_service = IMAPService(temp_user)
        print(temp_user, test_config)
        success, message = imap_service.test_connection()
        
        if success:
            # Save configuration to user's profile
            current_user.imap_config = test_config
            db.session.commit()
            
            # Redirect to folder selection modal after successful connection
            return imap_folders_modal()
            #response.headers['HX-Trigger'] = 'open-modal'
        else:
            response = make_response(render_template('partials/imap_config_modal.html',
                                                   errors={'general': message}, server=server, port=port, username=username, use_ssl=use_ssl))
            response.headers['HX-Retarget'] = '#imap-modal'
            response.headers['HX-Reswap'] = 'outerHTML'
        
        return response
        
    except Exception as e:
        logging.exception("Error testing IMAP connection: %s", e)
        print(e)
        errors = {'general': 'An unexpected error occurred. Please try again.'}
        response = make_response(render_template('partials/imap_config_modal.html', errors=errors, server=server, port=port, username=username, use_ssl=use_ssl))
        response.headers['HX-Retarget'] = '#imap-modal'
        response.headers['HX-Reswap'] = 'outerHTML'
        return response

@imap_bp.route('/api/imap/folders', methods=['GET'])
@login_required
def get_imap_folders():
    """Get folders from IMAP server without creating database records."""
    try:
        if not current_user.imap_config:
            return jsonify({'error': 'No IMAP configuration found. Please configure IMAP first.'}), 400
        
        # Test connection first
        imap_service = IMAPService(current_user)
        
        # Get folders from IMAP server
        imap_folders = imap_service.get_folders()
        
        if not imap_folders:
            return jsonify({'error': 'No folders found on IMAP server'}), 400
        
        # Deduplicate folders by name to prevent creating multiple entries for the same folder
        unique_folders = []
        seen_names = set()
        for imap_folder in imap_folders:
            folder_name = imap_folder['name']
            
            # Skip special folders that might not be needed
            if folder_name.lower() in ['sent', 'drafts', 'spam', 'trash']:
                continue
            
            # Use case-insensitive comparison for deduplication
            folder_name_lower = folder_name.lower()
            if folder_name_lower not in seen_names:
                unique_folders.append(imap_folder)
                seen_names.add(folder_name_lower)
        
        return jsonify({'folders': unique_folders})
            
    except Exception as e:
        logging.exception("Error getting IMAP folders: %s", e)
        print(e)
        return jsonify({'error': 'An unexpected error occurred while fetching folders'}), 500

@imap_bp.route('/api/imap/sync-selected', methods=['POST'])
@login_required
def sync_selected_folders():
    """Sync only the selected folders from IMAP server with processed email tracking."""
    try:
        if not current_user.imap_config:
            return jsonify({'error': 'No IMAP configuration found. Please configure IMAP first.'}), 400
        
        # Get selected folder names and types from form data
        selected_folders = {}
        for key, value in request.form.items():
            if key.startswith('folder_'):
                folder_name = value
                # Check if there's a corresponding folder type
                type_key = f'folder_type_{key.split("_")[1]}'
                folder_type = request.form.get(type_key, 'destination')  # Default to 'destination'
                selected_folders[folder_name] = folder_type
        
        if not selected_folders:
            return jsonify({'error': 'No folders selected'}), 400
        
        # Test connection first
        imap_service = IMAPService(current_user)
        
        # Get folders from IMAP server
        imap_folders = imap_service.get_folders()
        
        if not imap_folders:
            return jsonify({'error': 'No folders found on IMAP server'}), 400
        
        # Deduplicate folders by name to prevent creating multiple entries for the same folder
        unique_folders = []
        seen_names = set()
        for imap_folder in imap_folders:
            folder_name = imap_folder['name']
            
            # Skip special folders that might not be needed
            if folder_name.lower() in ['sent', 'drafts', 'spam', 'trash']:
                continue
            
            # Only include folders that were selected by the user
            if folder_name in selected_folders:
                # Use case-insensitive comparison for deduplication
                folder_name_lower = folder_name.lower()
                if folder_name_lower not in seen_names:
                    # Add the selected folder type
                    imap_folder['selected_type'] = selected_folders[folder_name]
                    unique_folders.append(imap_folder)
                    seen_names.add(folder_name_lower)
        
        # Process each selected unique folder
        synced_count = 0
        processed_emails_service = ProcessedEmailsService(current_user)
        
        # Create a list of folders to process
        folders_to_process = []
        
        for imap_folder in unique_folders:
            folder_name = imap_folder['name'].strip()
            folder_type = imap_folder.get('selected_type', 'destination')  # Get the selected type
            
            # Handle nested folder names (convert slashes to underscores or keep as-is)
            # According to requirements, nested folders should be created with slashes in the name
            display_name = folder_name
            
            # Check if folder already exists
            existing_folder = Folder.query.filter_by(
                user_id=current_user.id,
                name=display_name
            ).first()
            
            if not existing_folder:
                # Create new folder with the selected type
                new_folder = Folder(
                    user_id=current_user.id,
                    name=display_name,
                    rule_text=f"Auto-synced from IMAP folder: {folder_name}",
                    priority=0,  # Default priority
                    folder_type=folder_type
                )
                db.session.add(new_folder)
                synced_count += 1
                folders_to_process.append(new_folder)
            else:
                # Update existing folder with the selected type and email counts
                existing_folder.folder_type = folder_type
                
                # Get all email UIDs in this folder
                email_uids = imap_service.get_folder_email_uids(folder_name)
                
                # Sync with processed emails service
                new_emails_count = processed_emails_service.sync_folder_emails(display_name, email_uids)
                print("NEW", new_emails_count)
                
                # Update counts
                pending_count = processed_emails_service.get_pending_count(display_name)
                existing_folder.pending_count = pending_count
                existing_folder.total_count = len(email_uids)
                
                # Get the most recent emails for this folder
                recent_emails = imap_service.get_recent_emails(folder_name, 3)
                existing_folder.recent_emails = recent_emails
                
                folders_to_process.append(existing_folder)
        
        db.session.commit()
        
        # Just trigger the folder list update and close the modal
        response = make_response('')
        response.headers['HX-Trigger'] = 'close-modal, folder-list-invalidated'
        return response
            
    except Exception as e:
        logging.exception("Error syncing selected IMAP folders: %s", e)
        print(e)
        db.session.rollback()
        return jsonify({'error': 'An unexpected error occurred'}), 500