"""
Core billing engine for broker subscription and billing management
"""

import logging
from datetime import datetime, date, timedelta
from typing import Dict, Any, Optional, List
from decimal import Decimal as Dec

from .subscription_manager import SubscriptionManager
from .fee_calculator import FeeCalculator
from .currency_converter import CurrencyConverter
from .exchange_rate_updater import ExchangeRateUpdater

logger = logging.getLogger(__name__)


class BillingEngine:
    """
    Core billing engine that orchestrates all billing operations.
    
    Features:
    - Subscription management
    - Fee calculation
    - Currency conversion
    - Invoice generation
    - Usage tracking
    - Transaction recording
    """
    
    def __init__(self, db_manager, message_bus=None):
        """
        Initialize billing engine.
        
        Args:
            db_manager: Database manager instance
            message_bus: Optional message bus for notifications
        """
        self.db_manager = db_manager
        self.message_bus = message_bus
        
        # Initialize sub-components
        self.subscription_manager = SubscriptionManager(db_manager)
        self.fee_calculator = FeeCalculator(db_manager)
        self.currency_converter = CurrencyConverter(db_manager)
        self.exchange_rate_updater = ExchangeRateUpdater(db_manager, message_bus)
        
        logger.info("BillingEngine initialized")
    
    # ==================== Subscription Operations ====================
    
    def create_broker_subscription(self, user_id: int, plan_type: str = 'free',
                                    currency: str = 'USD', timezone: str = 'UTC',
                                    start_trial: bool = False) -> Dict[str, Any]:
        """Create a new broker subscription."""
        return self.subscription_manager.create_subscription(
            user_id, plan_type, currency, timezone, start_trial
        )
    
    def get_broker_subscription(self, user_id: int) -> Optional[Dict[str, Any]]:
        """Get broker subscription details."""
        return self.subscription_manager.get_subscription(user_id)
    
    def upgrade_subscription(self, user_id: int, new_plan_type: str,
                              currency: Optional[str] = None,
                              timezone: Optional[str] = None) -> Dict[str, Any]:
        """Upgrade or downgrade a subscription."""
        return self.subscription_manager.upgrade_subscription(
            user_id, new_plan_type, currency, timezone
        )
    
    def cancel_subscription(self, user_id: int, immediate: bool = False) -> Dict[str, Any]:
        """Cancel a subscription."""
        return self.subscription_manager.cancel_subscription(user_id, immediate)
    
    def suspend_subscription(self, user_id: int, reason: Optional[str] = None) -> Dict[str, Any]:
        """Suspend a subscription."""
        return self.subscription_manager.suspend_subscription(user_id, reason)
    
    def reactivate_subscription(self, user_id: int) -> Dict[str, Any]:
        """Reactivate a suspended subscription."""
        return self.subscription_manager.reactivate_subscription(user_id)
    
    # ==================== Fee Operations ====================
    
    def calculate_transaction_fee(self, user_id: int, transaction_amount: Dec,
                                   currency: str = 'USD') -> Dict[str, Any]:
        """
        Calculate transaction fee for a broker.
        
        Args:
            user_id: Broker user ID
            transaction_amount: Transaction amount
            currency: Transaction currency
            
        Returns:
            Dict with fee details
        """
        subscription = self.get_broker_subscription(user_id)
        if not subscription:
            return {
                'success': False,
                'error': 'Subscription not found'
            }
        
        return self.fee_calculator.calculate_transaction_fee(
            subscription, transaction_amount, currency
        )
    
    def calculate_revenue_share(self, user_id: int, revenue_amount: Dec,
                                  currency: str = 'USD') -> Dict[str, Any]:
        """
        Calculate revenue share for a broker.
        
        Args:
            user_id: Broker user ID
            revenue_amount: Revenue amount
            currency: Revenue currency
            
        Returns:
            Dict with revenue share details
        """
        subscription = self.get_broker_subscription(user_id)
        if not subscription:
            return {
                'success': False,
                'error': 'Subscription not found'
            }
        
        return self.fee_calculator.calculate_revenue_share(
            subscription, revenue_amount, currency
        )
    
    def get_plan_limits(self, plan_type: str) -> Dict[str, Any]:
        """Get limits for a subscription plan."""
        return self.fee_calculator.get_plan_limits(plan_type)
    
    def check_api_key_limit(self, user_id: int) -> Dict[str, Any]:
        """Check if broker can create more API keys."""
        subscription = self.get_broker_subscription(user_id)
        if not subscription:
            return {
                'can_create': False,
                'error': 'Subscription not found'
            }
        
        # Get current API key count
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import ApiKeyModel
                count = session.query(ApiKeyModel).filter_by(
                    user_id=user_id,
                    is_active=True
                ).count()
                
                return self.fee_calculator.check_api_key_limit(subscription, count)
            finally:
                session.close()
        except Exception as e:
            logger.error(f"Failed to check API key limit: {e}")
            return {
                'can_create': False,
                'error': str(e)
            }
    
    # ==================== Currency Operations ====================
    
    def convert_currency(self, amount: Dec, from_currency: str, 
                          to_currency: str, use_historical: bool = False,
                          historical_date: Optional[date] = None) -> Dec:
        """Convert amount between currencies."""
        return self.currency_converter.convert(
            amount, from_currency, to_currency, use_historical, historical_date
        )
    
    def get_exchange_rate(self, from_currency: str, to_currency: str) -> Optional[float]:
        """Get current exchange rate."""
        return self.currency_converter._get_current_rate(from_currency, to_currency)
    
    def get_all_exchange_rates(self, base_currency: str = 'USD') -> Dict[str, float]:
        """Get all exchange rates relative to base currency."""
        return self.currency_converter.get_all_rates(base_currency)
    
    def update_exchange_rates(self, force: bool = False) -> Dict[str, Any]:
        """Update all exchange rates."""
        return self.exchange_rate_updater.update_all_rates(force)
    
    def update_currency_rate(self, currency_code: str, force: bool = False) -> Dict[str, Any]:
        """Update exchange rate for a specific currency."""
        return self.exchange_rate_updater.update_currency_rate(currency_code, force)
    
    def start_exchange_rate_updates(self):
        """Start background exchange rate updates."""
        self.exchange_rate_updater.start_background_updates()
    
    def stop_exchange_rate_updates(self):
        """Stop background exchange rate updates."""
        self.exchange_rate_updater.stop_background_updates()
    
    # ==================== Transaction Operations ====================
    
    def record_transaction(self, user_id: int, transaction_type: str,
                            amount: Dec, currency: str,
                            reference_id: Optional[str] = None,
                            reference_type: Optional[str] = None,
                            description: Optional[str] = None,
                            payment_gateway: Optional[str] = None,
                            payment_gateway_transaction_id: Optional[str] = None) -> Dict[str, Any]:
        """
        Record a financial transaction for a broker.
        
        Args:
            user_id: Broker user ID
            transaction_type: Type of transaction
            amount: Transaction amount
            currency: Transaction currency
            reference_id: Optional reference ID
            reference_type: Optional reference type
            description: Optional description
            payment_gateway: Optional payment gateway name
            payment_gateway_transaction_id: Optional gateway transaction ID
            
        Returns:
            Dict with transaction details
        """
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import BrokerTransactionModel, BrokerSubscriptionModel
                
                # Get subscription
                subscription = session.query(BrokerSubscriptionModel).filter_by(
                    user_id=user_id
                ).first()
                
                if not subscription:
                    return {
                        'success': False,
                        'error': 'Subscription not found'
                    }
                
                # Create transaction
                transaction = BrokerTransactionModel(
                    user_id=user_id,
                    subscription_id=subscription.id,
                    transaction_type=transaction_type,
                    amount=amount,
                    currency=currency,
                    reference_id=reference_id,
                    reference_type=reference_type,
                    status='completed',
                    payment_gateway=payment_gateway,
                    payment_gateway_transaction_id=payment_gateway_transaction_id,
                    description=description
                )
                
                session.add(transaction)
                session.commit()
                
                logger.info(f"Recorded transaction for user {user_id}: {transaction_type} {amount} {currency}")
                
                return {
                    'success': True,
                    'transaction_id': transaction.id,
                    'transaction_type': transaction_type,
                    'amount': float(amount),
                    'currency': currency,
                    'status': 'completed'
                }
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to record transaction: {e}")
            return {
                'success': False,
                'error': str(e)
            }
    
    def get_transactions(self, user_id: int, transaction_type: Optional[str] = None,
                          status: Optional[str] = None, from_date: Optional[date] = None,
                          to_date: Optional[date] = None, limit: int = 100,
                          offset: int = 0) -> List[Dict[str, Any]]:
        """
        Get transaction history for a broker.
        
        Args:
            user_id: Broker user ID
            transaction_type: Filter by type
            status: Filter by status
            from_date: Start date filter
            to_date: End date filter
            limit: Max results
            offset: Pagination offset
            
        Returns:
            List of transaction dicts
        """
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import BrokerTransactionModel
                
                query = session.query(BrokerTransactionModel).filter_by(user_id=user_id)
                
                if transaction_type:
                    query = query.filter_by(transaction_type=transaction_type)
                if status:
                    query = query.filter_by(status=status)
                if from_date:
                    query = query.filter(BrokerTransactionModel.created_at >= from_date)
                if to_date:
                    query = query.filter(BrokerTransactionModel.created_at <= to_date)
                
                transactions = query.order_by(
                    BrokerTransactionModel.created_at.desc()
                ).limit(limit).offset(offset).all()
                
                return [
                    {
                        'id': txn.id,
                        'transaction_type': txn.transaction_type,
                        'amount': float(txn.amount),
                        'currency': txn.currency,
                        'status': txn.status,
                        'reference_id': txn.reference_id,
                        'description': txn.description,
                        'payment_gateway': txn.payment_gateway,
                        'created_at': txn.created_at.isoformat() if txn.created_at else None
                    }
                    for txn in transactions
                ]
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to get transactions: {e}")
            return []
    
    # ==================== Usage Tracking ====================
    
    def record_usage(self, user_id: int, bets_count: int = 0,
                      bet_amount: Dec = Dec('0'), bet_currency: str = 'USD',
                      transactions_count: int = 0,
                      transaction_amount: Dec = Dec('0'),
                      transaction_currency: str = 'USD',
                      api_calls: int = 0) -> Dict[str, Any]:
        """
        Record usage statistics for a broker.
        
        Args:
            user_id: Broker user ID
            bets_count: Number of bets
            bet_amount: Total bet amount
            bet_currency: Bet currency
            transactions_count: Number of transactions
            transaction_amount: Total transaction amount
            transaction_currency: Transaction currency
            api_calls: Number of API calls
            
        Returns:
            Dict with result
        """
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import BrokerUsageStatsModel, BrokerSubscriptionModel
                
                # Get subscription
                subscription = session.query(BrokerSubscriptionModel).filter_by(
                    user_id=user_id
                ).first()
                
                if not subscription:
                    return {
                        'success': False,
                        'error': 'Subscription not found'
                    }
                
                today = date.today()
                period_start = subscription.billing_cycle_start
                period_end = subscription.billing_cycle_end
                
                # Get or create usage stats for current period
                usage = session.query(BrokerUsageStatsModel).filter_by(
                    user_id=user_id,
                    period_start=period_start,
                    period_end=period_end
                ).first()
                
                if not usage:
                    usage = BrokerUsageStatsModel(
                        user_id=user_id,
                        subscription_id=subscription.id,
                        period_start=period_start,
                        period_end=period_end,
                        total_bets=0,
                        total_bet_amount=Dec('0'),
                        total_bet_currency=bet_currency,
                        total_transactions=0,
                        total_transaction_amount=Dec('0'),
                        total_transaction_currency=transaction_currency,
                        total_revenue_share=Dec('0'),
                        total_revenue_share_currency='USD',
                        total_fees=Dec('0'),
                        total_fees_currency='USD',
                        api_calls=0,
                        active_api_keys=0
                    )
                    session.add(usage)
                
                # Update usage
                usage.total_bets += bets_count
                usage.total_bet_amount += bet_amount
                usage.total_transactions += transactions_count
                usage.total_transaction_amount += transaction_amount
                usage.api_calls += api_calls
                
                session.commit()
                
                return {
                    'success': True,
                    'usage_id': usage.id
                }
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to record usage: {e}")
            return {
                'success': False,
                'error': str(e)
            }
    
    def get_usage_stats(self, user_id: int, period_start: Optional[date] = None,
                         period_end: Optional[date] = None) -> Optional[Dict[str, Any]]:
        """
        Get usage statistics for a broker.
        
        Args:
            user_id: Broker user ID
            period_start: Optional period start
            period_end: Optional period end
            
        Returns:
            Dict with usage stats or None
        """
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import BrokerUsageStatsModel, BrokerSubscriptionModel
                
                if not period_start or not period_end:
                    # Get current billing period
                    subscription = session.query(BrokerSubscriptionModel).filter_by(
                        user_id=user_id
                    ).first()
                    
                    if subscription:
                        period_start = subscription.billing_cycle_start
                        period_end = subscription.billing_cycle_end
                
                usage = session.query(BrokerUsageStatsModel).filter_by(
                    user_id=user_id,
                    period_start=period_start,
                    period_end=period_end
                ).first()
                
                if not usage:
                    return None
                
                return {
                    'period_start': str(usage.period_start),
                    'period_end': str(usage.period_end),
                    'total_bets': usage.total_bets,
                    'total_bet_amount': float(usage.total_bet_amount),
                    'total_bet_currency': usage.total_bet_currency,
                    'total_transactions': usage.total_transactions,
                    'total_transaction_amount': float(usage.total_transaction_amount),
                    'total_transaction_currency': usage.total_transaction_currency,
                    'total_revenue_share': float(usage.total_revenue_share),
                    'total_fees': float(usage.total_fees),
                    'api_calls': usage.api_calls,
                    'active_api_keys': usage.active_api_keys
                }
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to get usage stats: {e}")
            return None
    
    # ==================== Invoice Operations ====================
    
    def generate_invoice(self, user_id: int, period_start: date,
                          period_end: date) -> Dict[str, Any]:
        """
        Generate an invoice for a broker for a billing period.
        
        Args:
            user_id: Broker user ID
            period_start: Billing period start
            period_end: Billing period end
            
        Returns:
            Dict with invoice details
        """
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import (
                    BrokerInvoiceModel, BrokerSubscriptionModel,
                    BrokerUsageStatsModel, BrokerTransactionModel
                )
                
                # Get subscription
                subscription = session.query(BrokerSubscriptionModel).filter_by(
                    user_id=user_id
                ).first()
                
                if not subscription:
                    return {
                        'success': False,
                        'error': 'Subscription not found'
                    }
                
                # Check if invoice already exists for this period
                existing = session.query(BrokerInvoiceModel).filter_by(
                    user_id=user_id,
                    invoice_date=period_start
                ).first()
                
                if existing:
                    return {
                        'success': False,
                        'error': 'Invoice already exists for this period',
                        'invoice_id': existing.id
                    }
                
                # Get usage stats
                usage = session.query(BrokerUsageStatsModel).filter_by(
                    user_id=user_id,
                    period_start=period_start,
                    period_end=period_end
                ).first()
                
                # Calculate invoice amounts
                monthly_fee = Dec(str(subscription.monthly_fee))
                transaction_fees = Dec('0')
                revenue_share = Dec('0')
                
                if usage:
                    transaction_fees = Dec(str(usage.total_fees))
                    revenue_share = Dec(str(usage.total_revenue_share))
                
                subtotal = monthly_fee + transaction_fees + revenue_share
                tax = Dec('0')  # Tax calculation can be added later
                total = subtotal + tax
                
                # Generate invoice number
                invoice_number = f"INV-{period_start.year}-{period_start.month:02d}-{user_id:04d}"
                
                # Create invoice items
                items = [
                    {
                        'description': f'Monthly Subscription - {subscription.plan_type.capitalize()} Plan',
                        'amount': float(monthly_fee),
                        'currency': subscription.monthly_fee_currency
                    }
                ]
                
                if transaction_fees > 0:
                    items.append({
                        'description': 'Transaction Fees',
                        'amount': float(transaction_fees),
                        'currency': subscription.monthly_fee_currency
                    })
                
                if revenue_share > 0:
                    items.append({
                        'description': 'Revenue Share',
                        'amount': float(revenue_share),
                        'currency': subscription.monthly_fee_currency
                    })
                
                # Create invoice
                import json
                invoice = BrokerInvoiceModel(
                    user_id=user_id,
                    subscription_id=subscription.id,
                    invoice_number=invoice_number,
                    invoice_date=period_start,
                    due_date=period_end,
                    subtotal=subtotal,
                    tax=tax,
                    total=total,
                    currency=subscription.monthly_fee_currency,
                    status='draft',
                    items=json.dumps(items)
                )
                
                session.add(invoice)
                session.commit()
                
                logger.info(f"Generated invoice {invoice_number} for user {user_id}")
                
                return {
                    'success': True,
                    'invoice_id': invoice.id,
                    'invoice_number': invoice_number,
                    'invoice_date': str(period_start),
                    'due_date': str(period_end),
                    'subtotal': float(subtotal),
                    'tax': float(tax),
                    'total': float(total),
                    'currency': subscription.monthly_fee_currency,
                    'status': 'draft',
                    'items': items
                }
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to generate invoice: {e}")
            return {
                'success': False,
                'error': str(e)
            }
    
    def get_invoices(self, user_id: int, status: Optional[str] = None,
                      limit: int = 20, offset: int = 0) -> List[Dict[str, Any]]:
        """
        Get invoices for a broker.
        
        Args:
            user_id: Broker user ID
            status: Filter by status
            limit: Max results
            offset: Pagination offset
            
        Returns:
            List of invoice dicts
        """
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import BrokerInvoiceModel
                
                query = session.query(BrokerInvoiceModel).filter_by(user_id=user_id)
                
                if status:
                    query = query.filter_by(status=status)
                
                invoices = query.order_by(
                    BrokerInvoiceModel.invoice_date.desc()
                ).limit(limit).offset(offset).all()
                
                return [
                    {
                        'id': inv.id,
                        'invoice_number': inv.invoice_number,
                        'invoice_date': str(inv.invoice_date),
                        'due_date': str(inv.due_date),
                        'subtotal': float(inv.subtotal),
                        'tax': float(inv.tax),
                        'total': float(inv.total),
                        'currency': inv.currency,
                        'status': inv.status,
                        'paid_date': str(inv.paid_date) if inv.paid_date else None,
                        'payment_method': inv.payment_method
                    }
                    for inv in invoices
                ]
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to get invoices: {e}")
            return []
    
    def get_invoice(self, invoice_id: int) -> Optional[Dict[str, Any]]:
        """Get invoice details by ID."""
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import BrokerInvoiceModel
                import json
                
                invoice = session.query(BrokerInvoiceModel).get(invoice_id)
                
                if not invoice:
                    return None
                
                return {
                    'id': invoice.id,
                    'user_id': invoice.user_id,
                    'invoice_number': invoice.invoice_number,
                    'invoice_date': str(invoice.invoice_date),
                    'due_date': str(invoice.due_date),
                    'subtotal': float(invoice.subtotal),
                    'tax': float(invoice.tax),
                    'total': float(invoice.total),
                    'currency': invoice.currency,
                    'status': invoice.status,
                    'paid_date': str(invoice.paid_date) if invoice.paid_date else None,
                    'payment_method': invoice.payment_method,
                    'payment_reference': invoice.payment_reference,
                    'items': json.loads(invoice.items) if invoice.items else [],
                    'notes': invoice.notes,
                    'created_at': invoice.created_at.isoformat() if invoice.created_at else None
                }
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to get invoice: {e}")
            return None
    
    def mark_invoice_paid(self, invoice_id: int, payment_method: str,
                           payment_reference: Optional[str] = None) -> Dict[str, Any]:
        """Mark an invoice as paid."""
        try:
            session = self.db_manager.get_session()
            try:
                from ..database.models import BrokerInvoiceModel
                
                invoice = session.query(BrokerInvoiceModel).get(invoice_id)
                
                if not invoice:
                    return {
                        'success': False,
                        'error': 'Invoice not found'
                    }
                
                invoice.status = 'paid'
                invoice.paid_date = date.today()
                invoice.payment_method = payment_method
                invoice.payment_reference = payment_reference
                
                session.commit()
                
                logger.info(f"Marked invoice {invoice.invoice_number} as paid")
                
                return {
                    'success': True,
                    'invoice_id': invoice.id,
                    'status': 'paid',
                    'paid_date': str(invoice.paid_date)
                }
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to mark invoice as paid: {e}")
            return {
                'success': False,
                'error': str(e)
            }
    
    # ==================== Reporting ====================
    
    def get_broker_summary(self, user_id: int) -> Dict[str, Any]:
        """
        Get a summary of broker account including subscription, usage, and billing.
        
        Args:
            user_id: Broker user ID
            
        Returns:
            Dict with broker summary
        """
        try:
            subscription = self.get_broker_subscription(user_id)
            usage = self.get_usage_stats(user_id)
            invoices = self.get_invoices(user_id, limit=5)
            
            # Get recent transactions
            transactions = self.get_transactions(user_id, limit=10)
            
            return {
                'success': True,
                'subscription': subscription,
                'usage': usage,
                'recent_invoices': invoices,
                'recent_transactions': transactions
            }
            
        except Exception as e:
            logger.error(f"Failed to get broker summary: {e}")
            return {
                'success': False,
                'error': str(e)
            }
    
    def get_billing_report(self, user_id: int, period: str = 'monthly',
                            year: Optional[int] = None,
                            month: Optional[int] = None) -> Dict[str, Any]:
        """
        Generate a billing report for a broker.
        
        Args:
            user_id: Broker user ID
            period: Report period ('monthly', 'quarterly', 'yearly')
            year: Year for report
            month: Month for monthly report
            
        Returns:
            Dict with billing report
        """
        try:
            # Calculate date range based on period
            today = date.today()
            if year is None:
                year = today.year
            if month is None:
                month = today.month
            
            if period == 'monthly':
                period_start = date(year, month, 1)
                if month == 12:
                    period_end = date(year + 1, 1, 1) - timedelta(days=1)
                else:
                    period_end = date(year, month + 1, 1) - timedelta(days=1)
            elif period == 'quarterly':
                quarter = (month - 1) // 3 + 1
                period_start = date(year, (quarter - 1) * 3 + 1, 1)
                period_end = date(year, quarter * 3 + 1, 1) - timedelta(days=1)
            else:  # yearly
                period_start = date(year, 1, 1)
                period_end = date(year, 12, 31)
            
            # Get data for period
            usage = self.get_usage_stats(user_id, period_start, period_end)
            transactions = self.get_transactions(
                user_id, from_date=period_start, to_date=period_end, limit=1000
            )
            invoices = self.get_invoices(user_id, limit=100)
            
            # Filter invoices for period
            period_invoices = [
                inv for inv in invoices
                if period_start <= date.fromisoformat(inv['invoice_date']) <= period_end
            ]
            
            # Calculate totals
            total_fees = sum(
                float(txn['amount']) for txn in transactions
                if txn['transaction_type'] in ['monthly_fee', 'transaction_fee', 'revenue_share']
            )
            
            return {
                'success': True,
                'period': period,
                'period_start': str(period_start),
                'period_end': str(period_end),
                'usage': usage,
                'transactions': transactions,
                'invoices': period_invoices,
                'total_fees': total_fees,
                'currency': usage.get('total_bet_currency', 'USD') if usage else 'USD'
            }
            
        except Exception as e:
            logger.error(f"Failed to generate billing report: {e}")
            return {
                'success': False,
                'error': str(e)
            }

    def get_billing_summary(self) -> Dict[str, Any]:
        """
        Get overall billing summary statistics for admin dashboard.
        
        Returns:
            Dictionary containing billing summary statistics
        """
        try:
            from ..database.models import (
                BrokerSubscriptionModel, BrokerTransactionModel,
                BrokerInvoiceModel, SubscriptionPlanModel
            )
            from sqlalchemy import func
            
            session = self.db_manager.get_session()
            try:
                # Get total subscriptions by status
                subscriptions_by_status = session.query(
                    BrokerSubscriptionModel.status,
                    func.count(BrokerSubscriptionModel.id)
                ).group_by(BrokerSubscriptionModel.status).all()
                
                # Get total revenue
                total_revenue = session.query(
                    func.sum(BrokerTransactionModel.amount)
                ).filter(
                    BrokerTransactionModel.transaction_type == 'payment',
                    BrokerTransactionModel.status == 'completed'
                ).scalar() or 0
                
                # Get total pending invoices
                pending_invoices = session.query(
                    func.sum(BrokerInvoiceModel.total)
                ).filter(BrokerInvoiceModel.status == 'pending').scalar() or 0
                
                # Get active subscriptions count
                active_subscriptions = session.query(
                    func.count(BrokerSubscriptionModel.id)
                ).filter(BrokerSubscriptionModel.status == 'active').scalar() or 0
                
                # Get subscriptions by plan type
                subscriptions_by_plan = session.query(
                    BrokerSubscriptionModel.plan_type,
                    func.count(BrokerSubscriptionModel.id)
                ).group_by(BrokerSubscriptionModel.plan_type).all()
                
                return {
                    'total_subscriptions': sum(count for _, count in subscriptions_by_status),
                    'active_subscriptions': active_subscriptions,
                    'subscriptions_by_status': dict(subscriptions_by_status),
                    'subscriptions_by_plan': dict(subscriptions_by_plan),
                    'total_revenue': float(total_revenue),
                    'pending_invoices': float(pending_invoices),
                    'currency': 'USD'
                }
            finally:
                session.close()
        except Exception as e:
            logger.error(f"Failed to get billing summary: {e}")
            return {
                'total_subscriptions': 0,
                'active_subscriptions': 0,
                'subscriptions_by_status': {},
                'subscriptions_by_plan': {},
                'total_revenue': 0.0,
                'pending_invoices': 0.0,
                'currency': 'USD'
            }