import requests
import logging
from .models import Fanpage, Flow, Node, Edge, ChatSession, MessageLog
from ai.local_ai_api import LocalAIApi

logger = logging.getLogger(__name__)

def send_fb_message(psid, access_token, message_content):
    """
    Sends a message to a Facebook user via the Graph API.
    message_content: dict matching Facebook's message object (e.g., {"text": "..."})
    """
    url = f"https://graph.facebook.com/v12.0/me/messages?access_token={access_token}"
    payload = {
        "recipient": {"id": psid},
        "message": message_content
    }
    try:
        response = requests.post(url, json=payload)
        response.raise_for_status()
        return response.json()
    except Exception as e:
        logger.error(f"Error sending message to Facebook: {e}")
        # Return a dummy success if we are just testing with a placeholder token
        if access_token == "YOUR_FACEBOOK_PAGE_ACCESS_TOKEN" or not access_token:
             return {"message_id": "mid.test"}
        return None

def get_next_node(session, message_text):
    """
    Determines the next node in the flow based on user input.
    Returns None if no matching edge is found.
    """
    fanpage = session.fanpage
    
    if not session.current_node:
        # Start of conversation: find the default flow and its start node
        flow = Flow.objects.filter(fanpage=fanpage, is_default=True).first()
        if not flow:
            flow = Flow.objects.filter(fanpage=fanpage).first()
        
        if flow:
            return Node.objects.filter(flow=flow, is_start_node=True).first()
        return None
    
    # We are in an active session, look for a matching edge
    edges = Edge.objects.filter(source_node=session.current_node)
    message_text_clean = message_text.strip().lower()
    
    for edge in edges:
        if edge.condition.lower() == message_text_clean:
            return edge.target_node
            
    # If no matching edge, return None to trigger AI fallback
    return None

def get_ai_fallback_response(message_text, session):
    """
    Generates an AI-powered response when no flow edge matches.
    """
    fanpage = session.fanpage
    # Get last 5 messages for context
    recent_logs = MessageLog.objects.filter(session=session).order_by('-timestamp')[:5]
    history = []
    # Reverse to get chronological order
    for log in reversed(list(recent_logs)):
        role = "user" if log.sender_type == 'user' else "assistant"
        history.append({"role": role, "content": log.message_text})
    
    system_prompt = f"You are a helpful AI assistant for the Facebook Page '{fanpage.name}'. "
    system_prompt += "Your goal is to answer questions and help users in a friendly manner. "
    
    if session.current_node:
        system_prompt += f"The user is currently at the stage '{session.current_node.name}' in our automated flow, but just asked something else."

    messages = [{"role": "system", "content": system_prompt}] + history
    
    logger.info(f"Triggering AI fallback for session {session.id}")
    response = LocalAIApi.create_response({
        "input": messages
    })
    
    if response.get("success"):
        ai_text = LocalAIApi.extract_text(response)
        if ai_text:
            return ai_text
            
    return "I'm sorry, I couldn't understand that. How else can I help you today?"

def handle_webhook_event(data):
    """
    Main entry point for processing Facebook webhook POST data.
    """
    if data.get('object') != 'page':
        return
        
    for entry in data.get('entry', []):
        for messaging_event in entry.get('messaging', []):
            sender_id = messaging_event.get('sender', {}).get('id')
            recipient_id = messaging_event.get('recipient', {}).get('id')
            
            if not sender_id or not recipient_id:
                continue
                
            # 1. Identify Fanpage
            try:
                fanpage = Fanpage.objects.get(page_id=recipient_id, is_active=True)
            except Fanpage.DoesNotExist:
                logger.warning(f"Received event for unknown or inactive Page ID: {recipient_id}")
                continue
                
            # 2. Extract Message
            message_text = ""
            if 'message' in messaging_event:
                message_text = messaging_event['message'].get('text', "")
            elif 'postback' in messaging_event:
                # Handle button clicks
                message_text = messaging_event['postback'].get('payload', "")
                
            if not message_text:
                continue
                
            # 3. Get or Create Session
            session, created = ChatSession.objects.get_or_create(
                psid=sender_id,
                fanpage=fanpage
            )
            
            # 4. Log User Message
            MessageLog.objects.create(
                session=session,
                sender_type='user',
                message_text=message_text
            )
            
            # 5. Determine Next Node
            next_node = get_next_node(session, message_text)
            
            if next_node:
                # 6. Send Flow Reply
                # Always log the attempt and update session for dev visibility
                bot_text = next_node.content.get('text', '[Non-text message]')
                MessageLog.objects.create(
                    session=session,
                    sender_type='bot',
                    message_text=bot_text
                )
                
                # Update Session
                session.current_node = next_node
                session.save()
                
                # Actual delivery attempt
                send_fb_message(sender_id, fanpage.access_token, next_node.content)
            else:
                # 9. Trigger AI Fallback
                ai_reply_text = get_ai_fallback_response(message_text, session)
                
                # Log AI Response first so it shows up even if delivery fails
                MessageLog.objects.create(
                    session=session,
                    sender_type='bot',
                    message_text=ai_reply_text
                )
                
                # Actual delivery attempt
                send_fb_message(sender_id, fanpage.access_token, {"text": ai_reply_text})
