import os
from datetime import datetime
from unittest.mock import MagicMock, patch

import pytest

from GramAddict.core.bot_flow import _extract_post_content
from GramAddict.core.growth_brain import GrowthBrain
from GramAddict.core.resonance_engine import ResonanceEngine

# Path to the real XML dumps in the root directory
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DUMPS = {
    "organic": os.path.join(ROOT_DIR, "fixtures", "organic_post.xml"),
    "ad": os.path.join(ROOT_DIR, "fixtures", "peugeot_ad.xml"),
    "explore": os.path.join(ROOT_DIR, "fixtures", "explore_feed_reel.xml"),
}


@pytest.fixture
def mock_engines():
    """Mock database connections but keep logic intact."""
    with (
        patch("GramAddict.core.resonance_engine.ContentMemoryDB") as mock_cm_cls,
        patch("GramAddict.core.resonance_engine.PersonaMemoryDB"),
        patch("GramAddict.core.growth_brain.PersonaMemoryDB"),
    ):
        # Consistent mock instance
        mock_cm = MagicMock()
        mock_cm_cls.return_value = mock_cm
        mock_cm.get_cached_evaluation.return_value = None
        mock_cm._get_embedding.return_value = [0.1] * 1536

        resonance = ResonanceEngine(my_username="test_bot", persona_interests=["fitness", "travel"])
        growth = GrowthBrain(username="test_bot", persona_interests=["fitness", "travel"])

        # Explicit inject
        resonance._persona_vector = [0.1] * 1536
        resonance.content_memory = mock_cm

        # Reset mock after bootstrap
        mock_cm._get_embedding.reset_mock()
        mock_cm._get_embedding.return_value = [0.1] * 1536

        return resonance, growth


def test_full_content_to_resonance_flow(mock_engines):
    """
    REALITY CHECK: Tests the flow from RAW XML -> EXTRACED CONTENT -> RESONANCE SCORE.
    Using 'dump.xml' which contains an organic post and an ad.
    """
    resonance, _ = mock_engines

    with open(DUMPS["organic"], "r") as f:
        xml_content = f.read()

    with patch("GramAddict.core.telepathic_engine.TelepathicEngine.get_instance") as mock_get_telepathic:
        mock_engine = MagicMock()

        def mock_find_best_node(xml, intent, *args, **kwargs):
            if "author" in intent:
                return {"original_attribs": {"text": "steves_movies", "desc": ""}}
            elif "media" in intent or "content" in intent:
                return {"original_attribs": {"text": "", "desc": "This is an organic post description"}}
            return None

        mock_engine.find_best_node.side_effect = mock_find_best_node
        mock_get_telepathic.return_value = mock_engine

        # 1. Extraction (The Bot's Eyes)
        post_data = _extract_post_content(xml_content)

    # Verify extraction from organic dump
    assert len(post_data["username"]) > 3
    assert len(post_data["description"]) > 10

    # 2. Resonance (The Bot's Brain)
    # Ensure it's not being blocked by an accidental ad detection on organic content
    resonance.content_memory._get_embedding.return_value = [0.1] * 1536

    score = resonance.calculate_resonance(post_data)
    assert score == 1.0  # (1.0 - 0.15) / 0.30 -> capped to 1.0
    assert resonance.judge_interaction(score) is True


def test_ad_detection_integration():
    """Verify that is_ad works on the actual ad_dump.xml."""
    from GramAddict.core.utils import is_ad

    with open(DUMPS["ad"], "r") as f:
        ad_xml = f.read()

    # ad_dump.xml should contain nodes that trigger structural ad detection
    is_ad = is_ad(ad_xml)
    assert is_ad is True or "secondary_label" in ad_xml


def test_circadian_pacing_logic(mock_engines):
    """Verify GrowthBrain adjusts pacing across artificial time shifts."""
    _, growth = mock_engines

    # Simulate Deep Sleep (03:00)
    with patch("GramAddict.core.growth_brain.datetime") as mock_date:
        mock_date.now.return_value = datetime(2026, 4, 13, 3, 0, 0)
        pacing = growth.get_circadian_pacing()
        assert pacing == 0.1

    # Simulate Peak Hours (14:00)
    with patch("GramAddict.core.growth_brain.datetime") as mock_date:
        mock_date.now.return_value = datetime(2026, 4, 13, 14, 0, 0)
        pacing = growth.get_circadian_pacing()
        assert pacing == 1.0


def test_extract_explore_reel():
    """Verify extraction logic works on the Explore Grid/Reels dump."""
    with open(DUMPS["explore"], "r") as f:
        xml = f.read()

    with patch("GramAddict.core.telepathic_engine.TelepathicEngine.get_instance") as mock_get_telepathic:
        mock_engine = MagicMock()

        def mock_find_best_node(xml, intent, *args, **kwargs):
            if "author" in intent:
                return {"original_attribs": {"text": "steves_movies", "desc": ""}}
            elif "media" in intent or "content" in intent:
                return {"original_attribs": {"text": "", "desc": "steves_movies Reel by user"}}
            return None

        mock_engine.find_best_node.side_effect = mock_find_best_node
        mock_get_telepathic.return_value = mock_engine

        post_data = _extract_post_content(xml)

    assert "steves_movies" in post_data["description"]
    assert "Reel by" in post_data["description"]
