from typing import Dict, Any
import sys
import logging
from datetime import datetime

# Add shared modules to path
sys.path.append('/app')

from shared.kafka_client import EventTypes
from app.models.user_profile import UserProfile
from app.models.user_preference import UserPreference
from app.models.user_role import UserRole
from bson import ObjectId

logger = logging.getLogger("account_service.auth_events")

class AuthEventHandler:
    """Handle events from the auth service"""
    
    @staticmethod
    async def handle_user_registered(event_data: Dict[str, Any]):
        """Handle user registration event from auth service"""
        try:
            user_id = ObjectId(event_data["user_id"])
            email = event_data["email"]
            username = event_data["username"]
            
            logger.info(f"Handling user registration for user_id: {user_id}")
            
            # Create user profile
            profile = await UserProfile.create_from_auth_user(
                user_id=user_id,
                email=email,
                username=username
            )
            
            # Create default preferences
            preferences = await UserPreference.create_default_preferences(user_id)
            
            # Assign default role
            await UserRole.assign_default_role(user_id)
            
            logger.info(f"Successfully created profile and preferences for user: {username}")
            
        except Exception as e:
            logger.error(f"Error handling user registration: {e}")
            raise

    @staticmethod
    async def handle_user_logged_in(event_data: Dict[str, Any]):
        """Handle user login event"""
        try:
            user_id = ObjectId(event_data["user_id"])
            
            # Update last seen timestamp
            profile = await UserProfile.find_one(UserProfile.user_id == user_id)
            if profile:
                await profile.update_last_seen()
            
        except Exception as e:
            logger.error(f"Error handling user login: {e}")

    @staticmethod
    async def handle_user_logged_out(event_data: Dict[str, Any]):
        """Handle user logout event"""
        try:
            # Could update last seen or clear cached data
            user_id = event_data["user_id"]
            logger.info(f"User logged out: {user_id}")
            
        except Exception as e:
            logger.error(f"Error handling user logout: {e}")

    @staticmethod
    async def handle_password_changed(event_data: Dict[str, Any]):
        """Handle password change event"""
        try:
            user_id = event_data["user_id"]
            
            # Could send notification or update security preferences
            logger.info(f"Password changed for user: {user_id}")
            
        except Exception as e:
            logger.error(f"Error handling password change: {e}")

    @staticmethod
    async def handle_account_deactivated(event_data: Dict[str, Any]):
        """Handle account deactivation event"""
        try:
            user_id = ObjectId(event_data["user_id"])
            
            # Update profile status
            profile = await UserProfile.find_one(UserProfile.user_id == user_id)
            if profile:
                profile.status = "suspended"
                await profile.save()
            
            # Revoke all user roles
            user_roles = await UserRole.get_user_roles(user_id)
            for role in user_roles:
                if role.is_active:
                    await role.revoke("account_deactivated")
            
            logger.info(f"Account deactivated for user: {user_id}")
            
        except Exception as e:
            logger.error(f"Error handling account deactivation: {e}")

    @staticmethod
    async def handle_account_activated(event_data: Dict[str, Any]):
        """Handle account activation event"""
        try:
            user_id = ObjectId(event_data["user_id"])
            
            # Update profile status
            profile = await UserProfile.find_one(UserProfile.user_id == user_id)
            if profile:
                profile.status = "active"
                await profile.save()
            
            # Restore default role if user has no roles
            user_roles = await UserRole.get_user_roles(user_id, active_only=True)
            if not user_roles:
                await UserRole.assign_default_role(user_id)
            
            logger.info(f"Account activated for user: {user_id}")
            
        except Exception as e:
            logger.error(f"Error handling account activation: {e}")

    @classmethod
    async def process_event(cls, event_type: str, event_data: Dict[str, Any]):
        """Process an event based on its type"""
        handlers = {
            EventTypes.USER_REGISTERED: cls.handle_user_registered,
            EventTypes.USER_LOGGED_IN: cls.handle_user_logged_in,
            EventTypes.USER_LOGGED_OUT: cls.handle_user_logged_out,
            EventTypes.PASSWORD_CHANGED: cls.handle_password_changed,
            EventTypes.ACCOUNT_DEACTIVATED: cls.handle_account_deactivated,
            EventTypes.ACCOUNT_ACTIVATED: cls.handle_account_activated,
        }
        
        handler = handlers.get(event_type)
        if handler:
            await handler(event_data)
        else:
            logger.warning(f"No handler for event type: {event_type}")
