import asyncio
import json
import logging
from motor.motor_asyncio import AsyncIOMotorClient
from beanie import init_beanie, Document
from typing import Optional
from datetime import datetime
from pydantic import Field

from ..core.config import settings
from .email_service import email_service
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '../../..'))
from shared.kafka_client import kafka_client, EventTypes, Topics

logger = logging.getLogger(__name__)

# Import User model to access user data
class User(Document):
    username: str
    email: str
    email_verification_token: Optional[str] = None
    password_reset_token: Optional[str] = None
    
    class Settings:
        name = "users"

class KafkaEventConsumer:
    def __init__(self):
        self.running = False
        self.consumer = None
        
    async def initialize_db(self):
        """Initialize database connection"""
        client = AsyncIOMotorClient(settings.mongodb_url)
        db = client[settings.db_name]
        await init_beanie(database=db, document_models=[User])
        logger.info("Database initialized")
    
    async def process_event(self, event_type: str, data: dict):
        """Process different event types"""
        try:
            logger.info(f"Processing event: {event_type} with data: {data}")
            
            if event_type == EventTypes.USER_REGISTERED:
                await self.handle_user_registered(data)
            elif event_type == "user.password.reset.requested":
                await self.handle_password_reset(data)
            elif event_type == "user.email.verified":
                await self.handle_email_verified(data)
            else:
                logger.info(f"Unhandled event type: {event_type}")
                
        except Exception as e:
            logger.error(f"Error processing event {event_type}: {str(e)}")
    
    async def handle_user_registered(self, data: dict):
        """Handle user registration event"""
        user_id = data.get("user_id")
        if not user_id:
            logger.error("No user_id in registration event")
            return
        
        # Fetch user from database
        from bson import ObjectId
        user = await User.find_one({"_id": ObjectId(user_id)})
        if not user:
            logger.error(f"User not found: {user_id}")
            return
        
        if user.email_verification_token:
            # Send verification email
            success = await email_service.send_verification_email(
                to_email=user.email,
                username=user.username,
                verification_token=user.email_verification_token
            )
            if success:
                logger.info(f"Verification email sent to {user.email}")
            else:
                logger.error(f"Failed to send verification email to {user.email}")
    
    async def handle_password_reset(self, data: dict):
        """Handle password reset request"""
        user_id = data.get("user_id")
        if not user_id:
            return
        
        from bson import ObjectId
        user = await User.find_one({"_id": ObjectId(user_id)})
        if not user or not user.password_reset_token:
            return
        
        await email_service.send_password_reset_email(
            to_email=user.email,
            username=user.username,
            reset_token=user.password_reset_token
        )
    
    async def handle_email_verified(self, data: dict):
        """Handle email verification completion"""
        user_id = data.get("user_id")
        if not user_id:
            return
        
        from bson import ObjectId
        user = await User.find_one({"_id": ObjectId(user_id)})
        if not user:
            return
        
        await email_service.send_welcome_email(
            to_email=user.email,
            username=user.username
        )
    
    async def start_consuming(self):
        """Start consuming Kafka events"""
        await self.initialize_db()
        
        self.running = True
        consumer = kafka_client.get_consumer(
            topics=[Topics.AUTH_EVENTS, Topics.USER_EVENTS],
            group_id=settings.kafka_group_id
        )
        
        logger.info(f"Started consuming from topics: {[Topics.AUTH_EVENTS, Topics.USER_EVENTS]}")
        
        try:
            for message in consumer:
                if not self.running:
                    break
                
                try:
                    event_data = message.value
                    event_type = event_data.get("event_type")
                    
                    # Process event asynchronously
                    await self.process_event(event_type, event_data)
                    
                except Exception as e:
                    logger.error(f"Error processing message: {str(e)}")
                    
        except Exception as e:
            logger.error(f"Consumer error: {str(e)}")
        finally:
            consumer.close()
            logger.info("Kafka consumer stopped")
    
    def stop_consuming(self):
        """Stop consuming events"""
        self.running = False
        if self.consumer:
            self.consumer.close()

# Global consumer instance
kafka_consumer = KafkaEventConsumer()
