# ================================================================
# services/notification/app/main.py - ENHANCED WITH SSE SUPPORT
# ================================================================
"""
Notification Service Main Application
Handles email, WhatsApp notifications and SSE for real-time alerts/recommendations
"""

from fastapi import FastAPI
from sqlalchemy import text
from app.core.config import settings
from app.core.database import database_manager
from app.api.notifications import router as notification_router
from app.api.notification_operations import router as notification_operations_router
from app.api.analytics import router as analytics_router
from app.api.audit import router as audit_router
from app.api.whatsapp_webhooks import router as whatsapp_webhooks_router
from app.api.public_contact import router as public_contact_router
from app.services.sse_service import SSEService
from app.services.notification_orchestrator import NotificationOrchestrator
from app.services.email_service import EmailService
from app.services.whatsapp_service import WhatsAppService
from app.consumers.po_event_consumer import POEventConsumer
from shared.service_base import StandardFastAPIService
from shared.clients.tenant_client import TenantServiceClient
from shared.monitoring.system_metrics import SystemMetricsCollector
import asyncio


class NotificationService(StandardFastAPIService):
    """sdsfsdfsd. - Notification Service with standardized setup"""

    expected_migration_version = "whatsapp001"

    async def verify_migrations(self):
        """Verify database schema matches the latest migrations."""
        try:
            async with self.database_manager.get_session() as session:
                result = await session.execute(text("SELECT version_num FROM alembic_version"))
                version = result.scalar()
                if version != self.expected_migration_version:
                    self.logger.error(f"Migration version mismatch: expected {self.expected_migration_version}, got {version}")
                    raise RuntimeError(f"Migration version mismatch: expected {self.expected_migration_version}, got {version}")
                self.logger.info(f"Migration verification successful: {version}")
        except Exception as e:
            self.logger.error(f"Migration verification failed: {e}")
            raise

    def __init__(self):
        # Define expected database tables for health checks
        notification_expected_tables = [
            'notifications', 'notification_templates', 'notification_preferences',
            'notification_logs', 'email_templates', 'whatsapp_messages', 'whatsapp_templates'
        ]

        self.sse_service = None
        self.orchestrator = None
        self.email_service = None
        self.whatsapp_service = None
        self.tenant_client = None
        self.po_consumer = None
        self.po_consumer_task = None

        # Define custom metrics for notification service
        notification_custom_metrics = {
            "notifications_sent_total": {
                "type": "counter",
                "description": "Total notifications sent",
                "labels": ["type", "status", "channel"]
            },
            "emails_sent_total": {
                "type": "counter",
                "description": "Total emails sent",
                "labels": ["status"]
            },
            "whatsapp_sent_total": {
                "type": "counter",
                "description": "Total WhatsApp messages sent",
                "labels": ["status"]
            },
            "sse_events_sent_total": {
                "type": "counter",
                "description": "Total SSE events sent",
                "labels": ["tenant", "event_type"]
            },
            "notification_processing_duration_seconds": {
                "type": "histogram",
                "description": "Time spent processing notifications"
            }
        }

        # Define custom health checks for notification service components
        #async def check_email_service():
        #    """Check email service health - service is ready even if credentials are invalid"""
        #    try:
        #        if not self.email_service:
        #            return False
        #        # Service is considered healthy if it's initialized, even if credentials fail
        #        # This allows the pod to be ready while external services may have config issues
        #        await self.email_service.health_check()
        #        return True
        #    except Exception as e:
                # Log but don't fail readiness - email service config issues shouldn't block the pod
        #        self.logger.error("Email service health check failed", error=str(e))
                # Return True to indicate service is ready (initialized) even if credentials are wrong
        #        return True

        #async def check_whatsapp_service():
        #    """Check WhatsApp service health - service is ready even if credentials are invalid"""
        #    try:
        #        if not self.whatsapp_service:
        #            return False
                # Service is considered healthy if it's initialized, even if credentials fail
        #        await self.whatsapp_service.health_check()
        #        return True
        #    except Exception as e:
                # Log but don't fail readiness - WhatsApp config issues shouldn't block the pod
        #        self.logger.error("WhatsApp service health check failed", error=str(e))
                # Return True to indicate service is ready (initialized) even if credentials are wrong
        #        return True

        async def check_sse_service():
            """Check SSE service health"""
            try:
                if self.sse_service:
                    metrics = self.sse_service.get_metrics()
                    return bool(metrics.get("redis_connected", False))
                return False
            except Exception as e:
                self.logger.error("SSE service health check failed", error=str(e))
                return False

        #async def check_messaging():
        #    """Check messaging service health"""
        #    try:
        #        from app.services.messaging import notification_publisher
        #        return bool(notification_publisher and notification_publisher.connected)
        #    except Exception as e:
        #        self.logger.error("Messaging health check failed", error=str(e))
        #        return False

        super().__init__(
            service_name="notification-service",
            app_name="Bakery Notification Service",
            description="Email, WhatsApp and SSE notification service for bakery alerts and recommendations",
            version="2.0.0",
            log_level=settings.LOG_LEVEL,
            cors_origins=getattr(settings, 'CORS_ORIGINS', ["*"]),
            api_prefix="",  # Empty because RouteBuilder already includes /api/v1
            database_manager=database_manager,
            expected_tables=notification_expected_tables,
            custom_health_checks={
            #    "email_service": check_email_service,
            #    "whatsapp_service": check_whatsapp_service,
                "sse_service": check_sse_service,
            #    "messaging": check_messaging
            },
            enable_messaging=True,
            custom_metrics=notification_custom_metrics
        )

    async def _setup_messaging(self):
        """Setup messaging for notification service using unified messaging"""
        # The base class will handle the unified messaging setup
        # For notification service, no additional setup is needed
        self.logger.info("Notification service messaging initialized")

    async def _cleanup_messaging(self):
        """Cleanup messaging for notification service"""
        # The base class will handle the unified messaging cleanup
        self.logger.info("Notification service messaging cleaned up")

    async def on_startup(self, app: FastAPI):
        """Custom startup logic for notification service"""
        # Verify migrations first
        await self.verify_migrations()

        # Call parent startup (includes database, messaging, etc.)
        await super().on_startup(app)

        # Initialize tenant client for fetching tenant-specific settings
        self.tenant_client = TenantServiceClient(settings)
        self.logger.info("Tenant service client initialized")

        # Initialize services
        self.email_service = EmailService()
        self.whatsapp_service = WhatsAppService(tenant_client=self.tenant_client)

        # Initialize system metrics collection
        system_metrics = SystemMetricsCollector("notification")
        self.logger.info("System metrics collection started")

        # Initialize SSE service
        self.sse_service = SSEService()
        await self.sse_service.initialize(settings.REDIS_URL)
        self.logger.info("SSE service initialized")

        # Create orchestrator
        self.orchestrator = NotificationOrchestrator(
            email_service=self.email_service,
            whatsapp_service=self.whatsapp_service,
            sse_service=self.sse_service
        )

        # Store services in app state
        app.state.orchestrator = self.orchestrator
        app.state.sse_service = self.sse_service
        app.state.email_service = self.email_service
        app.state.whatsapp_service = self.whatsapp_service

        # Initialize and start PO event consumer
        self.po_consumer = POEventConsumer(
            email_service=self.email_service,
            whatsapp_service=self.whatsapp_service
        )

        # Start consuming PO approved events in background
        # Initialize unified messaging publisher
        from shared.messaging import UnifiedEventPublisher, RabbitMQClient

        rabbitmq_client = RabbitMQClient(settings.RABBITMQ_URL, "notification-service")
        if await rabbitmq_client.connect():
            notification_publisher = UnifiedEventPublisher(rabbitmq_client, "notification-service")
            self.po_consumer_task = asyncio.create_task(
                self.po_consumer.consume_po_approved_event(notification_publisher)
            )
            self.logger.info("PO event consumer started successfully")
        else:
            self.logger.warning("RabbitMQ not connected, PO event consumer not started")

        app.state.po_consumer = self.po_consumer

    async def on_shutdown(self, app: FastAPI):
        """Custom shutdown logic for notification service"""
        # Cancel PO consumer task
        if self.po_consumer_task and not self.po_consumer_task.done():
            self.po_consumer_task.cancel()
            try:
                await self.po_consumer_task
            except asyncio.CancelledError:
                self.logger.info("PO event consumer task cancelled")

        # Shutdown SSE service
        if self.sse_service:
            await self.sse_service.shutdown()
            self.logger.info("SSE service shutdown completed")

    def get_service_features(self):
        """Return notification-specific features"""
        return [
            "email_notifications",
            "whatsapp_notifications",
            "sse_real_time_updates",
            "notification_templates",
            "notification_orchestration",
            "messaging_integration",
            "multi_channel_support"
        ]

    def setup_custom_endpoints(self):
        """Setup custom endpoints for notification service"""
        # SSE metrics endpoint
        @self.app.get("/sse-metrics")
        async def sse_metrics():
            """Get SSE service metrics"""
            if self.sse_service:
                try:
                    sse_metrics = self.sse_service.get_metrics()
                    return {
                        'active_tenants': sse_metrics.get('active_tenants', 0),
                        'total_connections': sse_metrics.get('total_connections', 0),
                        'active_listeners': sse_metrics.get('active_listeners', 0),
                        'redis_connected': bool(sse_metrics.get('redis_connected', False))
                    }
                except Exception as e:
                    return {"error": str(e)}
            return {"error": "SSE service not available"}

        # Metrics endpoint
        # Note: Metrics are exported via OpenTelemetry OTLP to SigNoz
        # The /metrics endpoint is not needed as metrics are pushed automatically
        # @self.app.get("/metrics")
        # async def metrics():
        #     """Prometheus metrics endpoint"""
        #     if self.metrics_collector:
        #         return self.metrics_collector.get_metrics()
        #     return {"metrics": "not_available"}


# Create service instance
service = NotificationService()

# Create FastAPI app with standardized setup
app = service.create_app(
    docs_url="/docs",
    redoc_url="/redoc"
)

# Setup standard endpoints
service.setup_standard_endpoints()

# Setup custom endpoints
service.setup_custom_endpoints()

# Include routers
# IMPORTANT: Register audit router FIRST to avoid route matching conflicts
# where {notification_id} would match literal paths like "audit-logs"
service.add_router(audit_router, tags=["audit-logs"])
service.add_router(whatsapp_webhooks_router, tags=["whatsapp-webhooks"])
service.add_router(public_contact_router, tags=["public-contact"])
service.add_router(notification_operations_router, tags=["notification-operations"])
service.add_router(analytics_router, tags=["notifications-analytics"])
service.add_router(notification_router, tags=["notifications"])

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
