"""
Main LLM module for Karishye AI chat functionality.

This module contains the main chat_with_karishye function that orchestrates
the conversation flow with natural AI-driven booking (no rigid question flow).
"""

import logging
from datetime import datetime
from app.agents.agents import karishye_agent, ChatContext
from app.agents import karishye_agent_tools  # Register tools
from app.utils.conversation_utils import load_chat_history
from app.utils.utils import (
    get_user_puja_state,
)
from app.constants import PUJA_PATTERNS

# -------------------------------
# Logger setup
# -------------------------------
logger = logging.getLogger(__name__)


# -------------------------------
# Helper Functions
# -------------------------------

def _format_for_whatsapp(text: str) -> str:
    """
    Convert markdown to WhatsApp format with proper spacing and readability.
    
    Converts:
    - Headers (# text) → text with spacing (plain text, no bold)
    - Bold (**text**) → *text*
    - Italic (_text_) → _text_ (preserved)
    - Links [text](url) → text: url
    - Lists → • item (bullets) or numbered
    - Code blocks → preserved with backticks
    - Removes HTML tags
    """
    import re
    
    if not text:
        return ""
    
    # 1. Handle code blocks first (preserve them)
    # Inline code: `text` → `text` (preserve)
    # Block code: ```text``` → text (extract content)
    text = re.sub(r'```[\w]*\n?(.*?)```', r'\1', text, flags=re.DOTALL)
    
    # 2. Remove HTML tags early
    text = re.sub(r'<[^>]+>', '', text)
    
    # 3. Headers: # text → text with extra line break after (plain text)
    text = re.sub(r'^#{1,6}\s+(.+)$', r'\1\n', text, flags=re.MULTILINE)
    
    # 4. Bold: **text** → *text* (WhatsApp bold)
    text = re.sub(r'\*\*(.+?)\*\*', r'*\1*', text)
    
    # 5. Bold alternative: __text__ → *text*
    text = re.sub(r'__(.+?)__', r'*\1*', text)
    
    # 6. Italic: _text_ stays as _text_ (WhatsApp italic format)
    # No conversion needed - markdown italic is already WhatsApp format
    
    # 7. Strikethrough: ~~text~~ → ~text~ (WhatsApp strikethrough)
    text = re.sub(r'~~(.+?)~~', r'~\1~', text)
    
    # 8. Links: [text](url) → text: url (with clear separation)
    text = re.sub(r'\[([^\]]+)\]\(([^\)]+)\)', r'\1: \2', text)
    
    # 9. Unordered lists: - item or * item → • item
    text = re.sub(r'^[\*\-]\s+', '• ', text, flags=re.MULTILINE)
    
    # 10. Numbered lists: 1. item → 1. item (preserve but ensure spacing)
    text = re.sub(r'^(\d+)\.\s+', r'\1. ', text, flags=re.MULTILINE)
    
    # 11. Clean up excessive whitespace (max 2 line breaks)
    text = re.sub(r'\n{3,}', '\n\n', text)
    
    # 12. Ensure spacing after headers and before lists
    text = re.sub(r'(\*[^\*]+\*)\n([•\d])', r'\1\n\n\2', text)
    
    # 13. Clean up any trailing/leading whitespace
    return text.strip()

def _validate_chat_inputs(user_id: str, session_id: str) -> None:
    """Validate required chat inputs."""
    if not session_id:
        logger.error(f"[chat_with_karishye] Missing session_id")
        raise ValueError("session_id is required for chat operations")


def _find_active_puja_session(user_id: str, session_id: str) -> tuple:
    """
    Find any active puja session for the user.
    
    Returns:
        tuple: (active_puja_state, active_puja_key) or (None, None)
    """
    for pattern_key, pattern_info in PUJA_PATTERNS.items():
        questions_key = pattern_info.get("questions_key", pattern_key)
        state = get_user_puja_state(user_id, questions_key, session_id)
        
        if state and state.get("puja_name"):
            # Check if not yet completed
            if not state.get("completed"):
                return state, questions_key
    
    return None, None


# -------------------------------
# Main Chat Function
# -------------------------------

async def chat_with_karishye(user_message: str, user_id: str = "default", session_id: str = None, 
                            phone_number: str = None, user_name: str = None, format_for_whatsapp: bool = False) -> str:
    """
    Main chat function with natural AI-driven booking flow.
    
    The AI agent now handles everything naturally:
    - Detects puja interest
    - Collects information conversationally (no rigid questions)
    - Name and phone are auto-provided from WhatsApp
    - Determines when enough info is gathered
    - Handles urgency and empathy naturally
    
    Args:
        user_message: The user's message
        user_id: User's unique identifier (required)
        session_id: Session identifier (required for proper session isolation)
        phone_number: Pre-collected phone number from WhatsApp
        user_name: Pre-collected user name from WhatsApp
        format_for_whatsapp: If True, format response for WhatsApp (plain text), else use markdown for web
    """
    try:
        # Step 1: Validate inputs
        _validate_chat_inputs(user_id, session_id)
        
        logger.debug("[chat_with_karishye] Processing chat request")
        
        # Step 2: Load chat history from WATI (if phone_number is available)
        chat_history = []
        if phone_number:
            chat_history = await load_chat_history(phone_number, limit=10)
        
        # Step 3: Let AI handle everything naturally
        # Format history for the prompt
        history_context = ""
        if chat_history and len(chat_history) > 0:
            history_context = "\n\nRecent conversation context:\n"
            for entry in chat_history:
                role = "Assistant" if entry["type"] == "assistant" else "User"
                history_context += f"{role}: {entry['message']}\n"
        
        # Add context about active booking if exists
        active_puja_state, active_puja_key = _find_active_puja_session(user_id, session_id)
        booking_context = ""
        if active_puja_state and not active_puja_state.get("completed"):
            puja_name = active_puja_state.get("puja_name", "")
            collected_info = active_puja_state.get("collected_info", {})
            if puja_name:
                booking_context = f"\n\n[Context: User is currently booking {puja_name}. "
                if collected_info:
                    collected_fields = ", ".join(collected_info.keys())
                    booking_context += f"Already collected: {collected_fields}. "
                booking_context += "Continue gathering missing information naturally.]"
        
        # Add user name context if available from WhatsApp
        name_context = ""
        if user_name:
            name_context = f"\n\n[User's name: {user_name}. Use naturally with 'garu' in appropriate contexts - confirmations, empathy, important questions. Don't overuse.]"
        
        enhanced_message = f"{history_context}{booking_context}{name_context}\n\nCurrent message: {user_message}"
        chat_context = ChatContext(user_id, session_id, phone_number, user_name)  # Pass WhatsApp data
        
        # Measure agent response time
        import time
        start_time = time.time()
        result = await karishye_agent.run(enhanced_message, deps=chat_context)
        end_time = time.time()
        response_time = end_time - start_time
        
        response = result.output.strip() if hasattr(result, 'output') else str(result)
        
        logger.info(f"[chat_with_karishye] Response in {response_time:.2f}s")
        
        # Format response based on platform
        if format_for_whatsapp:
            response = _format_for_whatsapp(response)
        
        return response
        
    except Exception as e:
        # Log error without stack trace to avoid exposing sensitive data in logs
        logger.error(f"[chat_with_karishye] Error: {type(e).__name__}")
        error_response = f"I apologize, but I encountered an error while processing your request: {str(e)}"
        
        return error_response
