"""
Mail Aggregator Service — barrel re-export.

All implementation split into:
  aggregator_imap — IMAP connection, sync, email parsing
  aggregator_smtp — SMTP connection, email sending

Multi-account IMAP aggregation with async support.
"""

import asyncio
import logging
from typing import Optional, List, Dict, Any

from .credentials import get_credentials_service
from .mail_db import get_email_accounts, get_unified_inbox
from .models import AccountTestResult
from .aggregator_imap import IMAPMixin, IMAPConnectionError
from .aggregator_smtp import SMTPMixin, SMTPConnectionError

logger = logging.getLogger(__name__)


class MailAggregator(IMAPMixin, SMTPMixin):
    """
    Aggregates emails from multiple IMAP accounts into a unified inbox.

    Features:
    - Connect to multiple IMAP accounts
    - Fetch and cache emails in PostgreSQL
    - Send emails via SMTP
    - Handle connection pooling
    """

    def __init__(self):
        self._credentials_service = get_credentials_service()
        self._imap_connections: Dict[str, Any] = {}
        self._sync_lock = asyncio.Lock()

    async def test_account_connection(
        self,
        imap_host: str,
        imap_port: int,
        imap_ssl: bool,
        smtp_host: str,
        smtp_port: int,
        smtp_ssl: bool,
        email_address: str,
        password: str,
    ) -> AccountTestResult:
        """
        Test IMAP and SMTP connection with provided credentials.

        Returns:
            AccountTestResult with connection status
        """
        result = AccountTestResult(
            success=False,
            imap_connected=False,
            smtp_connected=False,
        )

        # Test IMAP
        imap_ok, imap_err, folders = await self.test_imap_connection(
            imap_host, imap_port, imap_ssl, email_address, password
        )
        result.imap_connected = imap_ok
        if folders:
            result.folders_found = folders
        if imap_err:
            result.error_message = imap_err

        # Test SMTP
        smtp_ok, smtp_err = await self.test_smtp_connection(
            smtp_host, smtp_port, smtp_ssl, email_address, password
        )
        result.smtp_connected = smtp_ok
        if smtp_err:
            if result.error_message:
                result.error_message += f"; {smtp_err}"
            else:
                result.error_message = smtp_err

        result.success = result.imap_connected and result.smtp_connected
        return result

    async def sync_all_accounts(self, user_id: str, tenant_id: Optional[str] = None) -> Dict[str, Any]:
        """
        Sync all accounts for a user.

        Returns:
            Dict with sync results per account
        """
        async with self._sync_lock:
            accounts = await get_email_accounts(user_id, tenant_id)
            results = {}

            for account in accounts:
                account_id = account["id"]
                try:
                    new_count, total_count = await self.sync_account(
                        account_id, user_id, max_emails=50
                    )
                    results[account_id] = {
                        "status": "success",
                        "new_emails": new_count,
                        "total_emails": total_count,
                    }
                except Exception as e:
                    results[account_id] = {
                        "status": "error",
                        "error": str(e),
                    }

            return results

    async def get_unified_inbox_emails(
        self,
        user_id: str,
        account_ids: Optional[List[str]] = None,
        categories: Optional[List[str]] = None,
        is_read: Optional[bool] = None,
        is_starred: Optional[bool] = None,
        limit: int = 50,
        offset: int = 0,
    ) -> List[Dict]:
        """
        Get unified inbox with all filters.

        Returns:
            List of email dictionaries
        """
        return await get_unified_inbox(
            user_id=user_id,
            account_ids=account_ids,
            categories=categories,
            is_read=is_read,
            is_starred=is_starred,
            limit=limit,
            offset=offset,
        )


# Global instance
_aggregator: Optional[MailAggregator] = None


def get_mail_aggregator() -> MailAggregator:
    """Get or create the global MailAggregator instance."""
    global _aggregator

    if _aggregator is None:
        _aggregator = MailAggregator()

    return _aggregator
