"""
Base class for knowledge extraction and generation.
"""

from loguru import logger
from abc import ABC, abstractmethod
from typing import List

from langchain_core.language_models.chat_models import BaseChatModel


class BaseKnowledgeGenerator(ABC):
    """Base class for generating knowledge from text."""

    def __init__(self, model: BaseChatModel):
        """
        Initialize the knowledge generator.

        Args:
            model: The language model to use
        """
        self.model = model

    @abstractmethod
    def generate(self, query: str, context: str) -> str:
        """
        Generate knowledge from the given query and context.

        Args:
            query: The query to generate knowledge for
            context: Additional context for knowledge generation

        Returns:
        """
        pass

    @abstractmethod
    def generate_knowledge(
        self,
        query: str,
        context: str = "",
        current_knowledge: str = "",
        questions: List[str] = None,
    ) -> str:
        """
        Generate knowledge based on query and context.

        Args:
            query: The query to generate knowledge for
            context: Additional context for knowledge generation
            current_knowledge: Current accumulated knowledge
            questions: List of questions to address

        Returns:
            str: Generated knowledge
        """
        pass

    @abstractmethod
    def generate_sub_knowledge(self, sub_query: str, context: str = "") -> str:
        """
        Generate knowledge for a sub-question.

        Args:
            sub_query: The sub-question to generate knowledge for
            context: Additional context for knowledge generation

        Returns:
            str: Generated knowledge for the sub-question
        """
        pass

    @abstractmethod
    def compress_knowledge(
        self, current_knowledge: str, query: str, section_links: list, **kwargs
    ) -> str:
        """
        Compress and summarize accumulated knowledge.

        Args:
            current_knowledge: The accumulated knowledge to compress
            query: The original research query
            section_links: List of source links
            **kwargs: Additional arguments

        Returns:
            str: Compressed knowledge
        """
        pass

    @abstractmethod
    def format_citations(self, links: List[str]) -> str:
        """
        Format source links into citations.

        Args:
            links: List of source links

        Returns:
            str: Formatted citations
        """
        pass

    def _validate_knowledge(self, knowledge: str) -> bool:
        """
        Validate the knowledge input.

        Args:
            knowledge: The knowledge to validate

        Returns:
            bool: True if knowledge is valid, False otherwise
        """
        if not knowledge or not isinstance(knowledge, str):
            logger.error("Invalid knowledge provided")
            return False
        return True

    def _validate_links(self, links: List[str]) -> bool:
        """
        Validate the source links.

        Args:
            links: List of source links to validate

        Returns:
            bool: True if links are valid, False otherwise
        """
        if not isinstance(links, list):
            logger.error("Invalid links format")
            return False
        if not all(isinstance(link, str) for link in links):
            logger.error("Invalid link type in links list")
            return False
        return True

    def _extract_key_points(self, knowledge: str) -> List[str]:
        """
        Extract key points from knowledge.

        Args:
            knowledge: The knowledge to analyze

        Returns:
            List[str]: List of key points
        """
        # This is a placeholder implementation
        # Specific implementations should override this method
        return knowledge.split("\n")
