"""
AI Assistant API Routes
"""

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import Optional
from pydantic import BaseModel

from ...shared.config.database import get_db
from ...security.middleware.auth import get_current_user
from ...auth.models.user import User
from ...auth.models.role import Role
from ..services.ai_chat_service import AIChatService
from ..services.ai_assistant_service import AIAssistantService
from ..services.ai_learning_service import AILearningService
from ..services.ai_training_scheduler import get_training_scheduler
from ...shared.config.logging_config import get_logger

logger = get_logger(__name__)

router = APIRouter(prefix="/ai-assistant", tags=["AI Assistant"])


class ChatMessageRequest(BaseModel):
    message: str
    context: Optional[dict] = None


class ChatMessageResponse(BaseModel):
    response: str
    intent: str
    data_used: dict
    timestamp: str


@router.post("/chat")
async def chat_with_ai(
    request: ChatMessageRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    Chat with AI assistant
    Accessible to all authenticated users (admin, staff, accountant, customer)
    Responses are filtered based on user role
    """
    try:
        # Load user role
        user_role = db.query(Role).filter(Role.id == current_user.role_id).first()
        if not user_role:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="User role not found"
            )
        
        # Initialize AI chat service with current user for role-based responses
        ai_service = AIChatService(db, current_user)
        
        # Generate response with role awareness
        result = ai_service.generate_response(
            user_query=request.message,
            context=request.context
        )
        
        return {
            "status": "success",
            "data": {
                "response": result["response"],
                "intent": result.get("intent", "unknown"),
                "data_used": result.get("data_used", {}),
                "timestamp": result.get("timestamp", ""),
                "user_role": user_role.name
            }
        }
    
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error in AI chat: {str(e)}", exc_info=True)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Error processing AI request: {str(e)}"
        )


@router.get("/status")
async def get_ai_status(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    Get comprehensive system status for AI assistant
    Status is filtered based on user role
    """
    try:
        # Load user role
        user_role = db.query(Role).filter(Role.id == current_user.role_id).first()
        if not user_role:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="User role not found"
            )
        
        # Initialize AI assistant with current user for role-based context
        ai_assistant = AIAssistantService(db, current_user)
        context = ai_assistant.generate_context_for_ai()
        
        return {
            "status": "success",
            "data": context
        }
    
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting AI status: {str(e)}", exc_info=True)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=str(e)
        )


@router.get("/rooms/occupied")
async def get_occupied_rooms(
    room_number: Optional[str] = None,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Get list of occupied rooms - Admin and Staff only"""
    try:
        user_role = db.query(Role).filter(Role.id == current_user.role_id).first()
        if not user_role or user_role.name not in ['staff', 'admin']:
            raise HTTPException(status_code=403, detail="Only staff and admin can access this information")
        
        ai_assistant = AIAssistantService(db, current_user)
        rooms = ai_assistant.search_occupied_rooms(room_number)
        
        return {"status": "success", "data": {"rooms": rooms}}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting occupied rooms: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/rooms/problems")
async def get_room_problems(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Get rooms with problems - Admin and Staff only"""
    try:
        user_role = db.query(Role).filter(Role.id == current_user.role_id).first()
        if not user_role or user_role.name not in ['staff', 'admin']:
            raise HTTPException(status_code=403, detail="Only staff and admin can access this information")
        
        ai_assistant = AIAssistantService(db, current_user)
        problems = ai_assistant.get_room_problems()
        
        return {"status": "success", "data": {"problems": problems}}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting room problems: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/chats/unanswered")
async def get_unanswered_chats(
    hours: int = 24,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Get unanswered chat messages - Admin and Staff only"""
    try:
        user_role = db.query(Role).filter(Role.id == current_user.role_id).first()
        if not user_role or user_role.name not in ['staff', 'admin']:
            raise HTTPException(status_code=403, detail="Only staff and admin can access this information")
        
        ai_assistant = AIAssistantService(db, current_user)
        chats = ai_assistant.get_unanswered_chats(hours)
        
        return {"status": "success", "data": {"chats": chats}}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting unanswered chats: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/training/trigger")
async def trigger_manual_training(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Manually trigger AI training - Admin only"""
    try:
        user_role = db.query(Role).filter(Role.id == current_user.role_id).first()
        if not user_role or user_role.name != 'admin':
            raise HTTPException(status_code=403, detail="Only admin can trigger manual training")
        
        learning_service = AILearningService(db)
        result = learning_service.auto_train_from_all_conversations()
        
        return {
            "status": "success",
            "message": "Training completed",
            "data": result
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error triggering training: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/training/analyze")
async def trigger_manual_analysis(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Manually trigger AI analysis and improvement - Admin only"""
    try:
        user_role = db.query(Role).filter(Role.id == current_user.role_id).first()
        if not user_role or user_role.name != 'admin':
            raise HTTPException(status_code=403, detail="Only admin can trigger manual analysis")
        
        learning_service = AILearningService(db)
        result = learning_service.auto_analyze_and_improve()
        
        return {
            "status": "success",
            "message": "Analysis completed",
            "data": result
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error triggering analysis: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/training/status")
async def get_training_status(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Get AI training status and metrics - Admin only"""
    try:
        user_role = db.query(Role).filter(Role.id == current_user.role_id).first()
        if not user_role or user_role.name != 'admin':
            raise HTTPException(status_code=403, detail="Only admin can view training status")
        
        from ..models.ai_conversation import AIConversation, AILearnedPattern, AIKnowledgeEntry, AITrainingMetrics
        from sqlalchemy import func
        from datetime import datetime, timedelta
        
        # Get statistics
        total_conversations = db.query(AIConversation).count()
        total_patterns = db.query(AILearnedPattern).filter(AILearnedPattern.is_active == True).count()
        total_knowledge = db.query(AIKnowledgeEntry).count()
        
        # Get recent metrics
        recent_metrics = db.query(AITrainingMetrics).order_by(
            AITrainingMetrics.metric_date.desc()
        ).limit(1).first()
        
        # Get scheduler status
        scheduler = get_training_scheduler()
        
        return {
            "status": "success",
            "data": {
                "scheduler_running": scheduler.running,
                "last_training": scheduler.last_training_time.isoformat() if scheduler.last_training_time else None,
                "last_analysis": scheduler.last_analysis_time.isoformat() if scheduler.last_analysis_time else None,
                "statistics": {
                    "total_conversations": total_conversations,
                    "total_patterns": total_patterns,
                    "total_knowledge_entries": total_knowledge,
                },
                "recent_metrics": {
                    "average_rating": float(recent_metrics.average_rating) if recent_metrics and recent_metrics.average_rating else None,
                    "helpful_rate": float(recent_metrics.helpful_rate) if recent_metrics and recent_metrics.helpful_rate else None,
                    "average_response_time_ms": recent_metrics.average_response_time_ms if recent_metrics else None,
                } if recent_metrics else None
            }
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting training status: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

