# services/external/app/main.py
"""
External Service Main Application
"""

from fastapi import FastAPI
from sqlalchemy import text
from app.core.config import settings
from app.core.database import database_manager
# Removed import of non-existent messaging module
# External service will use unified messaging from base class
from shared.service_base import StandardFastAPIService
from shared.redis_utils import initialize_redis, close_redis
# Include routers
from app.api import weather_data, traffic_data, city_operations, calendar_operations, audit, poi_context, geocoding, poi_refresh_jobs
from app.services.poi_scheduler import start_scheduler, stop_scheduler


class ExternalService(StandardFastAPIService):
    """External Data Service with standardized setup"""

    expected_migration_version = "00001"

    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
        external_expected_tables = [
            'weather_data', 'weather_forecasts', 'traffic_data',
            'traffic_measurement_points', 'traffic_background_jobs',
            'tenant_poi_contexts', 'poi_refresh_jobs'
        ]

        # Define custom API checks
        async def check_weather_api():
            """Check weather API configuration"""
            try:
                return bool(settings.AEMET_API_KEY)
            except Exception as e:
                self.logger.error("Weather API check failed", error=str(e))
                return False

        async def check_traffic_api():
            """Check traffic API configuration"""
            try:
                return bool(settings.MADRID_OPENDATA_API_KEY)
            except Exception as e:
                self.logger.error("Traffic API check failed", error=str(e))
                return False

        # Define custom metrics for external service
        external_custom_metrics = {
            "weather_api_calls_total": {
                "type": "counter",
                "description": "Total weather API calls"
            },
            "weather_api_success_total": {
                "type": "counter",
                "description": "Successful weather API calls"
            },
            "weather_api_failures_total": {
                "type": "counter",
                "description": "Failed weather API calls"
            },
            "traffic_api_calls_total": {
                "type": "counter",
                "description": "Total traffic API calls"
            },
            "traffic_api_success_total": {
                "type": "counter",
                "description": "Successful traffic API calls"
            },
            "traffic_api_failures_total": {
                "type": "counter",
                "description": "Failed traffic API calls"
            },
            "data_collection_jobs_total": {
                "type": "counter",
                "description": "Data collection jobs"
            },
            "data_records_stored_total": {
                "type": "counter",
                "description": "Data records stored"
            },
            "data_quality_issues_total": {
                "type": "counter",
                "description": "Data quality issues detected"
            },
            "weather_api_duration_seconds": {
                "type": "histogram",
                "description": "Weather API call duration"
            },
            "traffic_api_duration_seconds": {
                "type": "histogram",
                "description": "Traffic API call duration"
            },
            "data_collection_duration_seconds": {
                "type": "histogram",
                "description": "Data collection job duration"
            },
            "data_processing_duration_seconds": {
                "type": "histogram",
                "description": "Data processing duration"
            }
        }

        super().__init__(
            service_name="external-service",
            app_name="Bakery External Data Service",
            description="External data collection service for weather, traffic, and events data",
            version="1.0.0",
            log_level=settings.LOG_LEVEL,
            cors_origins=settings.CORS_ORIGINS,
            api_prefix="",  # Empty because RouteBuilder already includes /api/v1
            database_manager=database_manager,
            expected_tables=external_expected_tables,
            custom_health_checks={
                "weather_api": check_weather_api,
                "traffic_api": check_traffic_api
            },
            custom_metrics=external_custom_metrics,
            enable_messaging=True
        )

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

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

    async def on_startup(self, app: FastAPI):
        """Custom startup logic for external service"""
        # Initialize Redis connection
        await initialize_redis(settings.REDIS_URL, db=0, max_connections=50)
        self.logger.info("Redis initialized for external service")

        # Start POI refresh scheduler
        await start_scheduler()
        self.logger.info("POI refresh scheduler started")

    async def on_shutdown(self, app: FastAPI):
        """Custom shutdown logic for external service"""
        # Stop POI refresh scheduler
        await stop_scheduler()
        self.logger.info("POI refresh scheduler stopped")
        
        # Close Redis connection
        await close_redis()
        self.logger.info("Redis connection closed")
        
        # Database cleanup is handled by the base class

    def get_service_features(self):
        """Return external-specific features"""
        return [
            "weather_data_collection",
            "traffic_data_collection",
            "aemet_integration",
            "madrid_opendata_integration",
            "data_quality_monitoring",
            "scheduled_collection_jobs",
            "external_api_monitoring"
        ]



# Create service instance
service = ExternalService()

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

# Setup standard endpoints
service.setup_standard_endpoints()

# Include routers
# IMPORTANT: Register audit router FIRST to avoid route matching conflicts
service.add_router(audit.router)
service.add_router(weather_data.router)
service.add_router(traffic_data.router)
service.add_router(city_operations.router)  # New v2.0 city-based optimized endpoints
service.add_router(calendar_operations.router)  # School calendars and hyperlocal data
service.add_router(poi_context.router)  # POI detection and location-based features
service.add_router(geocoding.router)  # Address search and geocoding
service.add_router(poi_refresh_jobs.router)  # POI refresh background jobs