"""Kafka task processor - handles task execution from the queue."""

import asyncio
import logging
import time
from typing import Dict, Any
from datetime import datetime

from src.services.kafka_service import kafka_service
from src.services.task_manager import task_manager
from src.models.task import TaskStatus
from src.config.settings import LOG_LEVEL

logging.basicConfig(level=getattr(logging, LOG_LEVEL))
logger = logging.getLogger(__name__)


class TaskProcessor:
    """Processes tasks from Kafka queue."""
    
    def __init__(self):
        self.running = False
        self.processed_count = 0
        self.error_count = 0
        self.start_time = None
    
    async def start(self):
        """Start the task processor."""
        self.running = True
        self.start_time = time.time()
        
        logger.info("🚀 Starting Task Processor...")
        
        # Connect to Kafka
        if not kafka_service.connect_consumer(
            group_id="task_processor_group",
            message_handler=self._process_message
        ):
            logger.error("❌ Failed to connect to Kafka")
            return
        
        logger.info("✅ Task Processor started successfully")
        
        # Keep the processor running
        try:
            while self.running:
                await asyncio.sleep(1)
        except KeyboardInterrupt:
            logger.info("🛑 Stopping Task Processor...")
            self.stop()
    
    def stop(self):
        """Stop the task processor."""
        self.running = False
        kafka_service.close()
        
        runtime = time.time() - self.start_time if self.start_time else 0
        logger.info(f"🏁 Task Processor stopped. Processed {self.processed_count} tasks in {runtime:.2f}s")
    
    def _process_message(self, message: Dict[str, Any]):
        """Process a message from Kafka."""
        try:
            message_type = message.get('type')
            task_id = message.get('task_id')
            
            logger.info(f"📨 Processing message: {message_type} - {task_id}")
            
            if message_type == 'scrape_task':
                asyncio.run(self._handle_scrape_task(message))
            elif message_type == 'bulk_scrape_task':
                asyncio.run(self._handle_bulk_scrape_task(message))
            else:
                logger.warning(f"⚠️ Unknown message type: {message_type}")
                return
            
            self.processed_count += 1
            logger.info(f"✅ Task {task_id} processed successfully")
            
        except Exception as e:
            self.error_count += 1
            logger.error(f"❌ Error processing message: {e}")
    
    async def _handle_scrape_task(self, message: Dict[str, Any]):
        """Handle a single scrape task."""
        task_id = message.get('task_id')
        
        try:
            # Update task status to processing
            task_stats = task_manager.get_task_status(task_id)
            if task_stats:
                task_stats.status = TaskStatus.PROCESSING
                task_stats.started_at = datetime.utcnow()
            
            # Execute the task using task manager
            await task_manager._execute_scrape_task(message)
            
        except Exception as e:
            logger.error(f"❌ Error handling scrape task {task_id}: {e}")
            task_manager._mark_task_failed(task_id, str(e))
    
    async def _handle_bulk_scrape_task(self, message: Dict[str, Any]):
        """Handle a bulk scrape task."""
        task_id = message.get('task_id')
        
        try:
            # Update task status to processing
            task_stats = task_manager.get_task_status(task_id)
            if task_stats:
                task_stats.status = TaskStatus.PROCESSING
                task_stats.started_at = datetime.utcnow()
            
            # Execute the bulk task using task manager
            await task_manager._execute_bulk_scrape_task(message)
            
        except Exception as e:
            logger.error(f"❌ Error handling bulk scrape task {task_id}: {e}")
            task_manager._mark_task_failed(task_id, str(e))
    
    def get_stats(self) -> Dict[str, Any]:
        """Get processor statistics."""
        runtime = time.time() - self.start_time if self.start_time else 0
        
        return {
            "running": self.running,
            "processed_count": self.processed_count,
            "error_count": self.error_count,
            "runtime": runtime,
            "tasks_per_minute": (self.processed_count / (runtime / 60)) if runtime > 0 else 0,
            "error_rate": (self.error_count / max(self.processed_count, 1)) * 100
        }


# Global task processor instance
task_processor = TaskProcessor()

if __name__ == "__main__":
    asyncio.run(task_processor.start())
