"""
Conversation Summarizer for efficient memory management
Creates periodic summaries to reduce memory footprint while preserving context
"""

import json
from typing import List, Dict, Any, Optional
from datetime import datetime
import logging

logger = logging.getLogger(__name__)


class ConversationSummarizer:
    """Creates intelligent summaries of conversations to manage memory efficiently"""

    def __init__(self, grok_client=None, summary_interval: int = 10):
        self.grok_client = grok_client
        self.summary_interval = summary_interval

    def should_summarize(self, message_count: int) -> bool:
        """Determine if conversation should be summarized"""
        return message_count >= self.summary_interval

    def create_summary(self, conversation_history: List[Dict[str, Any]]) -> str:
        """Create a comprehensive summary of the conversation"""

        if not conversation_history:
            return ""

        try:
            # Use LLM for intelligent summarization if available
            if self.grok_client:
                return self._summarize_with_llm(conversation_history)
            else:
                return self._summarize_with_rules(conversation_history)
        except Exception as e:
            logger.error(f"Summary creation failed: {e}")
            return self._summarize_with_rules(conversation_history)

    def _summarize_with_llm(self, conversation_history: List[Dict[str, Any]]) -> str:
        """Use LLM for intelligent conversation summarization"""

        # Format conversation for LLM
        conversation_text = self._format_conversation_for_llm(conversation_history)

        prompt = f"""
        Create a concise but comprehensive summary of this conversation. Focus on:

        1. Main topics discussed
        2. User's key interests or concerns
        3. Any decisions made or conclusions reached
        4. User's expertise level or background (if apparent)
        5. Any preferences or preferences expressed
        6. Action items or next steps mentioned

        Keep the summary under 300 words but capture all essential information.

        Conversation:
        {conversation_text}
        """

        try:
            summary = self.grok_client.chat_complete(prompt)
            return summary.strip()
        except Exception as e:
            logger.error(f"LLM summarization failed: {e}")
            return self._summarize_with_rules(conversation_history)

    def _summarize_with_rules(self, conversation_history: List[Dict[str, Any]]) -> str:
        """Rule-based summarization as fallback"""

        summary_parts = []

        # Extract basic information
        topics = self._extract_topics(conversation_history)
        user_interests = self._extract_user_interests(conversation_history)
        expertise_level = self._assess_expertise_level(conversation_history)
        preferences = self._extract_preferences(conversation_history)

        if topics:
            summary_parts.append(f"Topics discussed: {', '.join(topics[:5])}")

        if user_interests:
            summary_parts.append(f"User interests: {', '.join(user_interests[:3])}")

        if expertise_level:
            summary_parts.append(f"User expertise: {expertise_level}")

        if preferences:
            summary_parts.append(f"Preferences: {', '.join(preferences[:3])}")

        # Add conversation flow summary
        total_messages = len(conversation_history)
        user_messages = len([m for m in conversation_history if m.get('role') == 'user'])
        assistant_messages = len([m for m in conversation_history if m.get('role') == 'assistant'])

        summary_parts.append(f"Conversation flow: {user_messages} user messages, {assistant_messages} assistant responses")

        return ". ".join(summary_parts)

    def _format_conversation_for_llm(self, conversation_history: List[Dict[str, Any]]) -> str:
        """Format conversation history for LLM consumption"""

        formatted_lines = []
        for i, message in enumerate(conversation_history[-self.summary_interval:], 1):
            role = message.get('role', 'unknown')
            content = message.get('content', '')[:300]  # Truncate long messages
            timestamp = message.get('timestamp', '')

            if timestamp:
                formatted_lines.append(f"{i}. {role.title()}: {content}")
            else:
                formatted_lines.append(f"{i}. {role.title()}: {content}")

        return "\n".join(formatted_lines)

    def _extract_topics(self, conversation_history: List[Dict[str, Any]]) -> List[str]:
        """Extract main topics from conversation"""

        topics = set()
        topic_keywords = {
            'business': ['business', 'startup', 'company', 'revenue', 'profit', 'market'],
            'finance': ['finance', 'investment', 'funding', 'money', 'budget'],
            'health': ['health', 'medical', 'therapy', 'treatment', 'wellness'],
            'legal': ['legal', 'law', 'regulation', 'license', 'compliance'],
            'psychology': ['psychology', 'mental', 'anxiety', 'depression', 'therapy'],
            'history': ['history', 'historical', 'ancient', 'civilization'],
            'hydroponics': ['hydroponics', 'hydro', 'soilless', 'dwc', 'nft'],
            'cannabis': ['cannabis', 'marijuana', 'cbd', 'thc', 'cultivation'],
            'survey': ['survey', 'question', 'answer', 'response']
        }

        for message in conversation_history:
            content = message.get('content', '').lower()

            for topic, keywords in topic_keywords.items():
                if any(keyword in content for keyword in keywords):
                    topics.add(topic)

        return list(topics)

    def _extract_user_interests(self, conversation_history: List[Dict[str, Any]]) -> List[str]:
        """Extract user interests from their messages"""

        interests = set()
        user_messages = [m for m in conversation_history if m.get('role') == 'user']

        interest_indicators = [
            'interested in', 'i like', 'i enjoy', 'passionate about',
            'focus on', 'work with', 'deal with', 'involved in'
        ]

        for message in user_messages:
            content = message.get('content', '').lower()

            for indicator in interest_indicators:
                if indicator in content:
                    # Extract words after the indicator
                    parts = content.split(indicator)
                    if len(parts) > 1:
                        after_indicator = parts[1].split('.')[0].strip()
                        if len(after_indicator.split()) <= 5:  # Reasonable length
                            interests.add(after_indicator)

        return list(interests)

    def _assess_expertise_level(self, conversation_history: List[Dict[str, Any]]) -> Optional[str]:
        """Assess user's expertise level from conversation"""

        expertise_indicators = {
            'expert': ['expert', 'professional', 'experienced', 'advanced', 'specialist', 'senior'],
            'intermediate': ['intermediate', 'some experience', 'moderate', 'knowledgeable', 'familiar'],
            'beginner': ['beginner', 'new', 'starting', 'novice', 'learning', 'first time', 'basic']
        }

        scores = {'expert': 0, 'intermediate': 0, 'beginner': 0}

        for message in conversation_history:
            content = message.get('content', '').lower()

            for level, indicators in expertise_indicators.items():
                for indicator in indicators:
                    if indicator in content:
                        scores[level] += 1

        # Return level with highest score, if any
        if max(scores.values()) > 0:
            return max(scores, key=scores.get)

        return None

    def _extract_preferences(self, conversation_history: List[Dict[str, Any]]) -> List[str]:
        """Extract user preferences from conversation"""

        preferences = set()
        user_messages = [m for m in conversation_history if m.get('role') == 'user']

        preference_indicators = [
            'prefer', 'like', 'want', 'need', 'better with',
            'rather have', 'would like', 'i prefer'
        ]

        for message in user_messages:
            content = message.get('content', '').lower()

            for indicator in preference_indicators:
                if indicator in content:
                    parts = content.split(indicator)
                    if len(parts) > 1:
                        preference = parts[1].split('.')[0].strip()
                        if len(preference.split()) <= 4:  # Reasonable length
                            preferences.add(preference)

        return list(preferences)

    def compress_memory(self, conversation_history: List[Dict[str, Any]],
                       max_memory_items: int = 50) -> List[Dict[str, Any]]:
        """Compress conversation history by creating summaries"""

        if len(conversation_history) <= max_memory_items:
            return conversation_history

        # Create summaries for older parts
        compressed_history = []

        # Keep recent messages as-is
        recent_messages = conversation_history[-20:]  # Keep last 20 messages

        # Summarize older messages in chunks
        older_messages = conversation_history[:-20]

        if older_messages:
            # Process in chunks
            chunk_size = self.summary_interval
            for i in range(0, len(older_messages), chunk_size):
                chunk = older_messages[i:i + chunk_size]

                if len(chunk) >= 5:  # Only summarize substantial chunks
                    summary = self.create_summary(chunk)
                    compressed_history.append({
                        'role': 'system',
                        'content': f"Summary of previous conversation: {summary}",
                        'type': 'summary',
                        'timestamp': chunk[-1].get('timestamp'),
                        'original_messages': len(chunk)
                    })
                else:
                    # Keep small chunks as-is
                    compressed_history.extend(chunk)

        # Add recent messages
        compressed_history.extend(recent_messages)

        # Ensure we don't exceed max_memory_items
        if len(compressed_history) > max_memory_items:
            # Keep the most recent items
            compressed_history = compressed_history[-max_memory_items:]

        return compressed_history

    def calculate_memory_efficiency(self, original_history: List[Dict[str, Any]],
                                  compressed_history: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Calculate memory compression statistics"""

        original_chars = sum(len(str(msg.get('content', ''))) for msg in original_history)
        compressed_chars = sum(len(str(msg.get('content', ''))) for msg in compressed_history)

        return {
            'original_messages': len(original_history),
            'compressed_messages': len(compressed_history),
            'original_characters': original_chars,
            'compressed_characters': compressed_chars,
            'compression_ratio': compressed_chars / original_chars if original_chars > 0 else 0,
            'space_savings': (original_chars - compressed_chars) / original_chars if original_chars > 0 else 0
        }
