from typing import List, Optional

from analogai.foundation.extensions.contradictions.contradiction_checker import is_belief_contradictory
from analogai.foundation.modules.belief.belief import Belief
from analogai.foundation.modules.belief.belief_service import BeliefService
from analogai.foundation.modules.categorical_deduction.categorical_deduction import CategoricalDeduction
from analogai.foundation.modules.conditionals.conditional_deduction import ConditionalDeduction
from analogai.foundation.modules.direct_statement.direct_statement import DirectStatement


class ContradictionsService:
    def __init__(self, belief_service: BeliefService):
        if belief_service is None:
            raise ValueError("belief_service is required")
        self._belief_service = belief_service

    def find_contradictory_beliefs(
        self,
        agent_id: str,
        user_id: Optional[str] = None,
        limit: int = 0,
        offset: int = 0,
    ) -> List[Belief]:
        beliefs = self._belief_service.get_all_for_agent(
            agent_id=agent_id,
            user_id=user_id,
        )
        contradictions: List[Belief] = []
        for belief in beliefs:
            if not self._has_deduction_and_statement(belief):
                continue
            if is_belief_contradictory(belief):
                contradictions.append(belief)
        if offset > 0:
            contradictions = contradictions[offset:]
        if limit and limit > 0:
            contradictions = contradictions[:limit]
        return contradictions

    @staticmethod
    def _has_deduction_and_statement(belief: Belief) -> bool:
        has_direct = any(isinstance(stmt, DirectStatement) for stmt in belief.statements)
        has_deduction = any(
            isinstance(stmt, (CategoricalDeduction, ConditionalDeduction))
            for stmt in belief.statements
        )
        return has_direct and has_deduction
