from unittest import TestCase

from analogai.foundation.modules.fact.basefact import BaseFact
from analogai.foundation.modules.fact.source.fact_source import UrlSource
from analogai.foundation.modules.fact.source.repositories.infrastructure.in_memory_fact_source_repository import (
    InMemoryFactSourceRepository,
)
from analogai.foundation.modules.fact.source.services.fact_source_service import FactSourceService


class _FakeFactService:
    def __init__(self, facts, belief_ids_by_turn):
        self._facts = facts
        self._belief_ids_by_turn = belief_ids_by_turn
        self.deleted_sources = []

    def get_facts_by_source(self, source_id):
        return [fact for fact in self._facts if fact.source_id == source_id]

    def delete_facts_by_source(self, source_id):
        matches = [fact for fact in self._facts if fact.source_id == source_id]
        self._facts = [fact for fact in self._facts if fact.source_id != source_id]
        self.deleted_sources.append(source_id)
        return matches

    def get_belief_ids_for_turn(self, turn_id: str):
        return list(self._belief_ids_by_turn.get(turn_id, []))

    def get_statement_ids_for_turn(self, turn_id: str):
        return []


class _FakeBelief:
    def __init__(self, belief_id, agent_id, statements=None):
        self.id = belief_id
        self.agent_id = agent_id
        self.statements = list(statements or [])


class _FakeBeliefService:
    def __init__(self, beliefs_by_agent):
        self._beliefs_by_agent = beliefs_by_agent
        self.deleted = []

    def get_all_for_agent(self, agent_id, user_id=None):
        return list(self._beliefs_by_agent.get(agent_id, []))

    def delete(self, belief):
        self.deleted.append(belief.id)


class TestFactSourceService(TestCase):
    def test_delete_source_deletes_facts_and_beliefs(self):
        source = UrlSource("https://example.com", agent_id="agent-1")
        fact = BaseFact(
            id="fact-1",
            turn_id="turn-1",
            user_id="user-1",
            agent_id="agent-1",
            embedding=None,
            source_id=source.id,
        )
        fact_service = _FakeFactService([fact], {"turn-1": {"belief-1"}})
        belief = _FakeBelief("belief-1", "agent-1")
        belief_service = _FakeBeliefService({"agent-1": [belief]})
        source_repo = InMemoryFactSourceRepository()
        source_repo.register_source(source)

        service = FactSourceService(
            fact_service=fact_service,
            belief_service=belief_service,
            source_repository=source_repo,
        )

        result = service.delete_source(source.id)

        self.assertEqual(result["fact_ids"], ["fact-1"])
        self.assertEqual(result["belief_ids"], ["belief-1"])
        self.assertEqual(belief_service.deleted, ["belief-1"])
        self.assertIsNone(source_repo.get_source(source.id))
