import json
from pathlib import Path
from .exceptions import ChatException
from .logger import get_logger

logger = get_logger(f"dracula.{__name__}")


class Memory:
    """
    Manages conversation history for Dracula.

    Stores messages in a list and automatically removes the oldest
    messages when the history exceeds the maximum size.

    Args:
        max_messages (int): Maximum number of messages to keep. Defaults to 10.
    """

    def __init__(self, max_messages: int = 10):
        self.history = []
        self.max_messages = max_messages

    def add_message(self, role: str, content: str):
        """
        Add a new message to the history.

        Args:
            role (str): Either 'user' or 'model'.
            content (str): The message content.
        """

        self.history.append({"role": role, "content": content})

        if len(self.history) > self.max_messages:
            self.history.pop(0)

    def get_history(self):
        """
        Return the full conversation history.

        Returns:
            list: List of message dictionaries.
        """

        return self.history

    def clear(self):
        """Clear all messages from history."""

        logger.debug("Memory cleared.")

        self.history = []

    def save(self, filepath: str):
        """
        Save conversation history to a JSON file.

        Args:
            filepath (str): Path to save the file.

        Raises:
            ChatException: If the file cannot be saved.
        """

        try:
            path = Path(filepath)
            path.parent.mkdir(parents=True, exist_ok=True)
            path.write_text(
                json.dumps(self.history, indent=4, ensure_ascii=False), encoding="utf-8"
            )

            logger.debug(f"History saved to {filepath}")
        except Exception as e:
            raise ChatException(f"Failed to save conversation: {str(e)}")

    def load(self, filepath: str):
        """
        Load conversation history from a JSON file.

        Args:
            filepath (str): Path to the file to load.

        Raises:
            ChatException: If the file does not exist or cannot be loaded.
        """

        try:
            path = Path(filepath)
            if not path.exists():
                raise ChatException(f"File not found: {filepath}")

            self.history = json.loads(path.read_text(encoding="utf-8"))

            logger.debug(f"History loaded from {filepath}")

        except ChatException:
            raise
        except Exception as e:
            raise ChatException(f"Failed to load conversation: {str(e)}")
