# ================================================================
# services/production/app/main.py
# ================================================================
"""
Production Service - FastAPI Application
Production planning and batch management service
"""

import time
from fastapi import FastAPI, Request
from sqlalchemy import text
from app.core.config import settings
from app.core.database import database_manager
from app.services.production_alert_service import ProductionAlertService
from app.services.production_scheduler import ProductionScheduler
from app.services.production_notification_service import ProductionNotificationService
from shared.service_base import StandardFastAPIService

# Import standardized routers
from app.api import (
    internal_demo,
    production_batches,
    production_schedules,
    production_operations,
    production_dashboard,
    analytics,
    quality_templates,
    equipment,
    orchestrator,  # NEW: Orchestrator integration endpoint
    production_orders_operations,  # Tenant deletion endpoints
    audit,
    ml_insights,  # ML insights endpoint
    batch,
    sustainability  # Sustainability metrics endpoints
)
from app.api.internal_alert_trigger import router as internal_alert_trigger_router


class ProductionService(StandardFastAPIService):
    """Production Service with standardized setup"""

    expected_migration_version = "001_initial_schema"

    async def on_startup(self, app):
        """Custom startup logic including migration verification"""
        await self.verify_migrations()
        await super().on_startup(app)

    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
        production_expected_tables = [
            'production_batches', 'production_schedules', 'production_capacity',
            'quality_check_templates', 'quality_checks', 'equipment'
        ]

        self.alert_service = None
        self.notification_service = None
        self.rabbitmq_client = None
        self.event_publisher = None
        # REMOVED: scheduler_service (replaced by Orchestrator Service)

        # Create custom checks for services
        async def check_alert_service():
            """Check production alert service health"""
            try:
                return bool(self.alert_service) if self.alert_service else False
            except Exception as e:
                self.logger.error("Alert service health check failed", error=str(e))
                return False

        super().__init__(
            service_name=settings.SERVICE_NAME,
            app_name=settings.APP_NAME,
            description=settings.DESCRIPTION,
            version=settings.VERSION,
            api_prefix="",  # Empty because RouteBuilder already includes /api/v1
            database_manager=database_manager,
            expected_tables=production_expected_tables,
            custom_health_checks={
                "alert_service": check_alert_service
            },
            enable_messaging=True  # Enable messaging support
        )

    async def _setup_messaging(self):
        """Setup messaging for production service using unified messaging"""
        from shared.messaging import UnifiedEventPublisher, RabbitMQClient
        try:
            self.rabbitmq_client = RabbitMQClient(settings.RABBITMQ_URL, service_name="production-service")
            await self.rabbitmq_client.connect()
            # Create unified event publisher
            self.event_publisher = UnifiedEventPublisher(self.rabbitmq_client, "production-service")
            self.logger.info("Production service unified messaging setup completed")
        except Exception as e:
            self.logger.error("Failed to setup production unified messaging", error=str(e))
            raise

    async def _cleanup_messaging(self):
        """Cleanup messaging for production service"""
        try:
            if self.rabbitmq_client:
                await self.rabbitmq_client.disconnect()
                self.logger.info("Production service messaging cleanup completed")
        except Exception as e:
            self.logger.error("Error during production messaging cleanup", error=str(e))

    async def on_startup(self, app: FastAPI):
        """Custom startup logic for production service"""
        # Initialize messaging
        await self._setup_messaging()

        # Initialize alert service with EventPublisher and database manager
        self.alert_service = ProductionAlertService(self.event_publisher, self.database_manager)
        await self.alert_service.start()
        self.logger.info("Production alert service started")

        # Initialize notification service with EventPublisher
        self.notification_service = ProductionNotificationService(self.event_publisher)
        self.logger.info("Production notification service initialized")

        # Initialize production scheduler with alert service and database manager
        self.production_scheduler = ProductionScheduler(self.alert_service, self.database_manager)
        await self.production_scheduler.start()
        self.logger.info("Production scheduler started")

        # Store services in app state
        app.state.alert_service = self.alert_service
        app.state.production_alert_service = self.alert_service  # Also store with this name for internal trigger
        app.state.notification_service = self.notification_service  # Notification service for state change events
        app.state.production_scheduler = self.production_scheduler  # Store scheduler for manual triggering
        app.state.event_publisher = self.event_publisher  # Store event publisher for ML insights

    async def on_shutdown(self, app: FastAPI):
        """Custom shutdown logic for production service"""
        # Stop production scheduler
        if hasattr(self, 'production_scheduler') and self.production_scheduler:
            await self.production_scheduler.stop()
            self.logger.info("Production scheduler stopped")

        # Stop alert service
        if self.alert_service:
            await self.alert_service.stop()
            self.logger.info("Alert service stopped")

        # Cleanup messaging
        await self._cleanup_messaging()

    def get_service_features(self):
        """Return production-specific features"""
        return [
            "production_planning",
            "batch_management",
            "production_scheduling",
            "orchestrator_integration",  # NEW: Orchestrator-driven scheduling
            "quality_control",
            "equipment_management",
            "capacity_planning",
            "alert_notifications"
        ]

    def setup_custom_middleware(self):
        """Setup custom middleware for production service"""
        @self.app.middleware("http")
        async def logging_middleware(request: Request, call_next):
            """Add request logging middleware"""
            start_time = time.time()
            response = await call_next(request)
            process_time = time.time() - start_time

            self.logger.info("HTTP request processed",
                            method=request.method,
                            url=str(request.url),
                            status_code=response.status_code,
                            process_time=round(process_time, 4))

            return response


# Create service instance
service = ProductionService()

# Create FastAPI app with standardized setup
app = service.create_app()

# Setup standard endpoints
service.setup_standard_endpoints()

# Setup custom middleware
service.setup_custom_middleware()

# Include standardized routers
# NOTE: Register more specific routes before generic parameterized routes
# IMPORTANT: Register audit router FIRST to avoid route matching conflicts
service.add_router(audit.router)
service.add_router(batch.router)
service.add_router(orchestrator.router)  # NEW: Orchestrator integration endpoint
service.add_router(production_orders_operations.router)  # Tenant deletion endpoints
service.add_router(quality_templates.router)  # Register first to avoid route conflicts
service.add_router(equipment.router)
service.add_router(production_batches.router)
service.add_router(production_schedules.router)
service.add_router(production_operations.router)
service.add_router(production_dashboard.router)
service.add_router(analytics.router)
service.add_router(sustainability.router)  # Sustainability metrics endpoints
service.add_router(internal_demo.router, tags=["internal-demo"])
service.add_router(ml_insights.router)  # ML insights endpoint
service.add_router(ml_insights.internal_router)  # Internal ML insights endpoint for demo cloning
service.add_router(internal_alert_trigger_router)  # Internal alert trigger for demo cloning

# REMOVED: test_production_scheduler endpoint
# Production scheduling is now triggered by the Orchestrator Service


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