# modules/studentact/claude_recommendations.py
import os
import anthropic
import streamlit as st
import logging
import time
import json
from datetime import datetime, timezone

# Local imports
from ..utils.widget_utils import generate_unique_key
from ..database.current_situation_mongo_db import store_current_situation_result

logger = logging.getLogger(__name__)

# Define text types
TEXT_TYPES = {
    'es': {
        'academic_article': 'artículo académico',
        'university_work': 'trabajo universitario',
        'general_communication': 'comunicación general'
    },
    'en': {
        'academic_article': 'academic article',
        'university_work': 'university work',
        'general_communication': 'general communication'
    },
    'fr': {
        'academic_article': 'article académique',
        'university_work': 'travail universitaire',
        'general_communication': 'communication générale'
    }
}

# Cache for recommendations to avoid redundant API calls
recommendation_cache = {}

def get_recommendation_cache_key(text, metrics, text_type, lang_code):
    """
    Generate a cache key for recommendations.
    """
    # Create a simple hash based on text content and metrics
    text_hash = hash(text[:1000])  # Only use first 1000 chars for hashing
    metrics_hash = hash(json.dumps(metrics, sort_keys=True))
    return f"{text_hash}_{metrics_hash}_{text_type}_{lang_code}"

def format_metrics_for_claude(metrics, lang_code, text_type):
    """
    Format metrics in a way that's readable for Claude
    """
    formatted_metrics = {}
    for key, value in metrics.items():
        if isinstance(value, (int, float)):
            formatted_metrics[key] = round(value, 2)
        else:
            formatted_metrics[key] = value
    
    # Add context about what type of text this is
    text_type_label = TEXT_TYPES.get(lang_code, {}).get(text_type, text_type)
    formatted_metrics['text_type'] = text_type_label
    
    return formatted_metrics

def generate_claude_recommendations(text, metrics, text_type, lang_code):
    """
    Generate personalized recommendations using Claude API.
    """
    try:
        api_key = os.environ.get("ANTHROPIC_API_KEY")
        if not api_key:
            logger.error("Claude API key not found in environment variables")
            return get_fallback_recommendations(lang_code)
        
        # Check cache first
        cache_key = get_recommendation_cache_key(text, metrics, text_type, lang_code)
        if cache_key in recommendation_cache:
            logger.info("Using cached recommendations")
            return recommendation_cache[cache_key]
        
        # Format metrics for Claude
        formatted_metrics = format_metrics_for_claude(metrics, lang_code, text_type)
        
        # Determine language for prompt
        if lang_code == 'es':
            system_prompt = """Eres un asistente especializado en análisis de textos académicos y comunicación escrita. 
            Tu tarea es analizar el texto del usuario y proporcionar recomendaciones personalizadas.
            Usa un tono constructivo y específico. Sé claro y directo con tus sugerencias.
            """
            user_prompt = f"""Por favor, analiza este texto de tipo '{formatted_metrics['text_type']}' 
            y proporciona recomendaciones personalizadas para mejorarlo.
            
            MÉTRICAS DE ANÁLISIS:
            {json.dumps(formatted_metrics, indent=2, ensure_ascii=False)}
            
            TEXTO A ANALIZAR:
            {text[:2000]}  # Limitamos el texto para evitar exceder tokens
            
            Proporciona tu análisis con el siguiente formato:
            1. Un resumen breve (2-3 frases) del análisis general 
            2. 3-4 recomendaciones específicas y accionables (cada una de 1-2 frases)
            3. Un ejemplo concreto de mejora tomado del propio texto del usuario
            4. Una sugerencia sobre qué herramienta de AIdeaText usar (Análisis Morfosintáctico, Análisis Semántico o Análisis del Discurso)
            
            Tu respuesta debe ser concisa y no exceder los 300 palabras."""
        else:
            # Default to English
            system_prompt = """You are an assistant specialized in analyzing academic texts and written communication.
            Your task is to analyze the user's text and provide personalized recommendations.
            Use a constructive and specific tone. Be clear and direct with your suggestions.
            """
            user_prompt = f"""Please analyze this text of type '{formatted_metrics['text_type']}' 
            and provide personalized recommendations to improve it.
            
            ANALYSIS METRICS:
            {json.dumps(formatted_metrics, indent=2, ensure_ascii=False)}
            
            TEXT TO ANALYZE:
            {text[:2000]}  # Limiting text to avoid exceeding tokens
            
            Provide your analysis with the following format:
            1. A brief summary (2-3 sentences) of the general analysis
            2. 3-4 specific and actionable recommendations (each 1-2 sentences)
            3. A concrete example of improvement taken from the user's own text
            4. A suggestion about which AIdeaText tool to use (Morphosyntactic Analysis, Semantic Analysis or Discourse Analysis)
            
            Your response should be concise and not exceed 300 words."""
        
        # Initialize Claude client
        client = anthropic.Anthropic(api_key=api_key)
        
        # Call Claude API
        start_time = time.time()
        response = client.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=1024,
            temperature=0.7,
            system=system_prompt,
            messages=[
                {"role": "user", "content": user_prompt}
            ]
        )
        logger.info(f"Claude API call completed in {time.time() - start_time:.2f} seconds")
        
        # Extract recommendations
        recommendations = response.content[0].text
        
        # Cache the result
        recommendation_cache[cache_key] = recommendations
        
        return recommendations
    except Exception as e:
        logger.error(f"Error generating recommendations with Claude: {str(e)}")
        return get_fallback_recommendations(lang_code)

def get_fallback_recommendations(lang_code):
    """
    Return fallback recommendations if Claude API fails
    """
    if lang_code == 'es':
        return """
        **Análisis General**
        Tu texto presenta una estructura básica adecuada, pero hay áreas que pueden mejorarse para mayor claridad y cohesión.

        **Recomendaciones**:
        - Intenta variar tu vocabulario para evitar repeticiones innecesarias
        - Considera revisar la longitud de tus oraciones para mantener un mejor ritmo
        - Asegúrate de establecer conexiones claras entre las ideas principales
        - Revisa la consistencia en el uso de tiempos verbales

        **Herramienta recomendada**: 
        Te sugerimos utilizar el Análisis Morfosintáctico para identificar patrones en tu estructura de oraciones.
        """
    else:
        return """
        **General Analysis**
        Your text presents an adequate basic structure, but there are areas that can be improved for better clarity and cohesion.
        
        **Recommendations**:
        - Try to vary your vocabulary to avoid unnecessary repetition
        - Consider reviewing the length of your sentences to maintain a better rhythm
        - Make sure to establish clear connections between main ideas
        - Check consistency in the use of verb tenses
        
        **Recommended tool**: 
        We suggest using Morphosyntactic Analysis to identify patterns in your sentence structure.
        """


#######################################

def store_recommendations(username, text, metrics, text_type, recommendations):
    """
    Store the recommendations in the database
    """
    try:
        # Importar la función de almacenamiento de recomendaciones
        from ..database.claude_recommendations_mongo_db import store_claude_recommendation
        
        # Guardar usando la nueva función especializada
        result = store_claude_recommendation(
            username=username,
            text=text,
            metrics=metrics,
            text_type=text_type,
            recommendations=recommendations
        )
        
        logger.info(f"Recommendations stored successfully: {result}")
        return result
    except Exception as e:
        logger.error(f"Error storing recommendations: {str(e)}")
        return False


##########################################
##########################################
def display_personalized_recommendations(text, metrics, text_type, lang_code, t):
    """
    Display personalized recommendations based on text analysis
    """
    try:
        # Generate recommendations
        recommendations = generate_claude_recommendations(text, metrics, text_type, lang_code)
        
        # Format and display recommendations in a nice container
        st.markdown("### 📝 " + t.get('recommendations_title', 'Personalized Recommendations'))
        
        with st.container():
            st.markdown(f"""
            <div style="padding: 20px; border-radius: 10px; 
                background-color: #f8f9fa; margin-bottom: 20px;">
                {recommendations}
            </div>
            """, unsafe_allow_html=True)
            
            # Add prompt to use assistant
            st.info("💡 **" + t.get('assistant_prompt', 'For further improvement:') + "** " + 
                   t.get('assistant_message', 'Open the virtual assistant (powered by Claude AI) in the upper left corner by clicking the arrow next to the logo.'))
            
            # Add save button
            col1, col2, col3 = st.columns([1,1,1])
            with col2:
                if st.button(
                    t.get('save_button', 'Save Analysis'),
                    key=generate_unique_key("claude_recommendations", "save"),
                    type="primary",
                    use_container_width=True
                ):
                    if 'username' in st.session_state:
                        success = store_recommendations(
                            st.session_state.username,
                            text,
                            metrics,
                            text_type,
                            recommendations
                        )
                        if success:
                            st.success(t.get('save_success', 'Analysis saved successfully'))
                        else:
                            st.error(t.get('save_error', 'Error saving analysis'))
                    else:
                        st.error(t.get('login_required', 'Please log in to save analysis'))
    
    except Exception as e:
        logger.error(f"Error displaying recommendations: {str(e)}")
        st.error(t.get('recommendations_error', 'Error generating recommendations. Please try again later.'))