from __future__ import annotations

from typing import TYPE_CHECKING

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

if TYPE_CHECKING:
    from analogai.foundation.modules.conditionals.hypothetical_statement import HypotheticalStatement


class ExpressionAssembler:
    def __init__(self):
        pass

    def build_notion_expression(self, caption: str, attributes=None) -> NotionExpression:
        return NotionExpression(
            caption=caption,
            children=[],
            context=[],
            attributes=attributes,
        )

    def build_notion_expression_from_notion(self, notion: Notion) -> NotionExpression:
        return NotionExpression(
            caption=notion.caption,
            children=[],
            context=[],
            attributes=notion.attributes,
        )

    def build_belief_expression(self, belief: Belief):
        from analogai.foundation.common.dtos.belief_expression import BeliefExpression

        subject_expression = self.build_notion_expression_from_notion(belief.subject_notion)
        object_expression = self.build_notion_expression_from_notion(belief.complement_notion)

        return BeliefExpression(
            subject_notion_expression=subject_expression,
            complement_notion_expression=object_expression,
            relation=belief.relation,
            probability=belief.probability,
            validity=belief.validity,
            modifier=belief.modifier,
        )

    def build_categorical_deduction_expression(self, inference: CategoricalDeduction):
        from analogai.foundation.common.dtos.categorical_deduction_expression import CategoricalDeductionExpression

        major_premise_expression = self.build_belief_expression(inference.major_premise)
        minor_premise_expression = self.build_belief_expression(inference.minor_premise)
        subject_expression = self.build_notion_expression_from_notion(inference.subject_notion)
        object_expression = self.build_notion_expression_from_notion(inference.complement_notion)

        return CategoricalDeductionExpression(
            major_premise_expression=major_premise_expression,
            minor_premise_expression=minor_premise_expression,
            subject_notion_expression=subject_expression,
            complement_notion_expression=object_expression,
            relation=inference.relation,
            probability=inference.probability,
            validity=inference.validity,
            modifier=inference.modifier,
        )

    def build_hypothetical_statement_expression(self, hypothetical: HypotheticalStatement):
        from analogai.foundation.common.dtos.hypothetical_statement_expression import HypotheticalStatementExpression
        from analogai.foundation.modules.conditionals.hypothetical_statement import HypotheticalStatement

        if not isinstance(hypothetical, HypotheticalStatement):
            raise TypeError("hypothetical must be a HypotheticalStatement")

        causes = [dict(getattr(cause, "criteria", {}) or {}) for cause in (hypothetical.causes or [])]
        effect_clause = dict(getattr(hypothetical.effect, "criteria", {}) or {})

        return HypotheticalStatementExpression(
            causes=causes,
            effect=effect_clause,
            validity=hypothetical.validity,
        )
