from typing import Optional, Dict, Any
from analogai.foundation.settings import config
from analogai.foundation.common.enums.criterion import Criterion
from analogai.foundation.modules.notion.notion import Notion
from analogai.foundation.modules.belief.belief import Belief
from analogai.foundation.modules.categorical_deduction.categorical_deduction import CategoricalDeduction
from analogai.foundation.common.dtos.notion_expression import NotionExpression
from analogai.foundation.common.utils.expression_assembler import ExpressionAssembler


class ExpressionFactory:
    def __init__(self):
        self._assembler = ExpressionAssembler(self._maybe_lemmatize_text, self._lemmatize_criteria)

    def _maybe_lemmatize_text(self, text: str) -> str:
        if not config.get("lemmatize", False):
            return text
        from analogai.foundation.common.utils.lemmatization import lemmatize_text
        return lemmatize_text(text)

    def _lemmatize_criteria(self, criteria: Dict[Criterion, Any]) -> Dict[Criterion, Any]:
        if not criteria:
            return {}
        normalized = dict(criteria)
        subject = normalized.get(Criterion.SubjectCaption)
        if subject is not None:
            normalized[Criterion.SubjectCaption] = self._maybe_lemmatize_text(str(subject))
        object_caption = normalized.get(Criterion.ObjectCaption)
        if object_caption is not None:
            normalized[Criterion.ObjectCaption] = self._maybe_lemmatize_text(str(object_caption))
        return normalized
    
    def create_notion_expression(self, caption: str, attributes=None) -> NotionExpression:
        return self._assembler.build_notion_expression(caption, attributes)
    
    def propagate_notion_expression(self, notion: Notion) -> NotionExpression:
        return self._assembler.build_notion_expression_from_notion(notion)
    
    def propagate_belief_expression(self, belief: Belief) -> "BeliefExpression":
        return self._assembler.build_belief_expression(belief)
    
    def propagate_categorical_deduction_expression(self, inference: CategoricalDeduction) -> "CategoricalDeductionExpression":
        return self._assembler.build_categorical_deduction_expression(inference)

    def propagate_hypothetical_statement_expression(self, hypothetical: "HypotheticalStatement") -> "HypotheticalStatementExpression":
        return self._assembler.build_hypothetical_statement_expression(hypothetical)

