"""
Riley Chat - Gemini AI integration for persona-based conversations
"""

import json
from pathlib import Path
from typing import Dict, List, Optional

from .loader import load_persona
from .utils import build_system_prompt

# Try to import google.generativeai, but don't fail if not installed
try:
    import google.generativeai as genai
    GEMINI_AVAILABLE = True
except ImportError:
    GEMINI_AVAILABLE = False
    genai = None


class Riley:
    """
    Main class for chatting with Riley personas using Gemini AI.
    
    Example:
        >>> from rilerary import Riley
        >>> riley = Riley(api_key="your-gemini-api-key")
        >>> riley.use_persona("chef_rile")
        >>> response = riley.chat("How do I make pasta?")
        >>> print(riley.history)
    """
    
    def __init__(self, api_key: str, model: str = "gemini-1.5-flash"):
        """
        Initialize Riley with a Gemini API key.
        
        Args:
            api_key: Your Google Gemini API key
            model: Gemini model to use (default: gemini-1.5-flash)
        
        Raises:
            ImportError: If google-generativeai is not installed
        """
        if not GEMINI_AVAILABLE:
            raise ImportError(
                "google-generativeai is required for Riley chat functionality. "
                "Install it with: pip install google-generativeai"
            )
        
        self._api_key = api_key
        self._model_name = model
        self._persona_name: Optional[str] = None
        self._persona_data: Optional[Dict] = None
        self._system_prompt: str = ""
        self._history: List[Dict[str, str]] = []
        self._chat_session = None
        
        # Configure Gemini
        genai.configure(api_key=api_key)
        self._model = genai.GenerativeModel(model)
    
    def use_persona(self, persona_name: str) -> "Riley":
        """
        Set the persona to use for conversations.
        
        Args:
            persona_name: Name of the persona (e.g., 'chef_rile', 'tech_rile')
            
        Returns:
            Self for method chaining
        """
        self._persona_name = persona_name
        self._persona_data = load_persona(persona_name)
        self._system_prompt = build_system_prompt(self._persona_data)
        self._chat_session = None  # Reset chat session for new persona
        return self
    
    def _get_chat_session(self):
        """Get or create a chat session with conversation history."""
        if self._chat_session is None:
            # Build conversation history for Gemini
            gemini_history = []
            for entry in self._history:
                gemini_history.append({
                    "role": "user",
                    "parts": [entry["question"]]
                })
                gemini_history.append({
                    "role": "model", 
                    "parts": [entry["answer"]]
                })
            
            self._chat_session = self._model.start_chat(history=gemini_history)
        
        return self._chat_session
    
    def chat(self, question: str) -> str:
        """
        Send a message and get a response from the persona.
        
        The question and answer are automatically stored in history.
        
        Args:
            question: Your question or message
            
        Returns:
            The persona's response
            
        Raises:
            ValueError: If no persona has been set
        """
        if self._persona_data is None:
            raise ValueError(
                "No persona set. Call use_persona() first. "
                "Example: riley.use_persona('chef_rile')"
            )
        
        # Build the full prompt with system instructions
        full_prompt = f"{self._system_prompt}\n\nUser: {question}"
        
        # If we have history, use chat session for context
        if self._history:
            chat = self._get_chat_session()
            response = chat.send_message(question)
        else:
            # First message - include system prompt
            response = self._model.generate_content(full_prompt)
        
        answer = response.text
        
        # Store in history
        self._history.append({
            "question": question,
            "answer": answer
        })
        
        # Reset chat session so next call includes updated history
        self._chat_session = None
        
        return answer
    
    @property
    def history(self) -> List[Dict[str, str]]:
        """
        Get the conversation history.
        
        Returns:
            List of dictionaries with 'question' and 'answer' keys
        """
        return self._history.copy()
    
    @property
    def persona(self) -> Optional[Dict]:
        """Get the current persona data."""
        return self._persona_data
    
    @property
    def persona_name(self) -> Optional[str]:
        """Get the current persona name."""
        return self._persona_name
    
    def clear_history(self) -> "Riley":
        """
        Clear the conversation history.
        
        Returns:
            Self for method chaining
        """
        self._history = []
        self._chat_session = None
        return self
    
    def save_history(self, filepath: str) -> None:
        """
        Save conversation history to a JSON file.
        
        Args:
            filepath: Path to save the history file
        """
        data = {
            "persona": self._persona_name,
            "history": self._history
        }
        
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=2, ensure_ascii=False)
    
    def load_history(self, filepath: str) -> "Riley":
        """
        Load conversation history from a JSON file.
        
        Args:
            filepath: Path to the history file
            
        Returns:
            Self for method chaining
        """
        with open(filepath, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        # Load persona if specified in history file
        if data.get("persona") and data["persona"] != self._persona_name:
            self.use_persona(data["persona"])
        
        self._history = data.get("history", [])
        self._chat_session = None  # Reset to rebuild with loaded history
        
        return self
    
    def __repr__(self) -> str:
        persona_info = self._persona_name or "None"
        return f"Riley(persona={persona_info}, history_length={len(self._history)})"
