"""Tests for discussion tools."""

from unittest.mock import MagicMock, patch

import pytest

from tests.conftest import MockMCP

# Sample document dict returned by _search_via_sdk
_SAMPLE_DOC = {
    "id": 12345,
    "title": "How to win Titanic",
    "votes": 42,
    "ownerUser": {"displayName": "alice"},
    "discussionDocument": {
        "messageMarkdown": "Here is my approach...",
        "forumName": "titanic",
    },
}

_SAMPLE_COMMENT = {
    "id": 99,
    "votes": 5,
    "ownerUser": {"displayName": "bob"},
    "discussionDocument": {
        "messageMarkdown": "Great post!",
    },
}


@pytest.fixture
def mcp():
    m = MockMCP()
    from kaggle_mcp import discussions
    discussions.register(m)
    return m


# ---------------------------------------------------------------------------
# discussions_search
# ---------------------------------------------------------------------------

def test_discussions_search_returns_results(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussions_search"]("titanic")
        assert "How to win Titanic" in result
        assert "alice" in result


def test_discussions_search_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussions_search"]("xyz")
        assert result == "No discussions found."


def test_discussions_search_passes_params(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        mcp.tools["discussions_search"]("titanic", sort_by="votes", source_type="competition", page_size=5)
        mock_search.assert_called_once_with(
            query="titanic", sort_by="votes", source_type="competition", page_size=5
        )


# ---------------------------------------------------------------------------
# discussions_list
# ---------------------------------------------------------------------------

def test_discussions_list_by_competition(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussions_list"](competition="titanic")
        assert "How to win Titanic" in result
        mock_search.assert_called_once_with(
            query="titanic", source_type="competition", page_size=20
        )


def test_discussions_list_by_dataset(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        mcp.tools["discussions_list"](dataset="uciml/iris")
        mock_search.assert_called_once_with(
            query="uciml/iris", source_type="dataset", page_size=20
        )


def test_discussions_list_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussions_list"]()
        assert result == "No discussions found."


# ---------------------------------------------------------------------------
# discussion_detail
# ---------------------------------------------------------------------------

def test_discussion_detail_found(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussion_detail"](12345)
        assert "How to win Titanic" in result
        assert "alice" in result
        assert "Here is my approach" in result


def test_discussion_detail_not_found(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussion_detail"](99999)
        assert "not found" in result.lower() or "99999" in result


# ---------------------------------------------------------------------------
# discussion_comments
# ---------------------------------------------------------------------------

def test_discussion_comments_returns_comments(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_COMMENT]
        result = mcp.tools["discussion_comments"](12345)
        assert "bob" in result
        assert "Great post!" in result


def test_discussion_comments_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussion_comments"](12345)
        assert "No comments found" in result


def test_discussion_comments_uses_comment_document_type(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_COMMENT]
        mcp.tools["discussion_comments"](12345, page_size=10)
        call_kwargs = mock_search.call_args[1]
        assert call_kwargs.get("document_type") == "COMMENT"


# ---------------------------------------------------------------------------
# discussion_comments_search
# ---------------------------------------------------------------------------

def test_discussion_comments_search(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_COMMENT]
        result = mcp.tools["discussion_comments_search"]("great post")
        assert "bob" in result
        assert "Great post!" in result


def test_discussion_comments_search_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussion_comments_search"]("xyz")
        assert result == "No comments found."


# ---------------------------------------------------------------------------
# discussions_by_source
# ---------------------------------------------------------------------------

def test_discussions_by_source_valid(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussions_by_source"]("competition")
        assert "How to win Titanic" in result
        assert "competition" in result


def test_discussions_by_source_invalid(mcp):
    result = mcp.tools["discussions_by_source"]("invalid_type")
    assert "Invalid source_type" in result


def test_discussions_by_source_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussions_by_source"]("dataset")
        assert "No discussions found" in result


# ---------------------------------------------------------------------------
# discussions_solutions
# ---------------------------------------------------------------------------

def test_discussions_solutions(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussions_solutions"](competition="titanic")
        assert "How to win Titanic" in result
        assert "Competition Solutions" in result


def test_discussions_solutions_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussions_solutions"]()
        assert "No competition solutions found." in result


# ---------------------------------------------------------------------------
# discussions_writeups
# ---------------------------------------------------------------------------

def test_discussions_writeups_valid_type(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussions_writeups"](write_up_type="knowledge")
        assert "How to win Titanic" in result
        assert "knowledge" in result


def test_discussions_writeups_invalid_type(mcp):
    result = mcp.tools["discussions_writeups"](write_up_type="invalid")
    assert "Invalid write_up_type" in result


def test_discussions_writeups_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussions_writeups"](write_up_type="blog")
        assert "No write-ups found" in result


# ---------------------------------------------------------------------------
# discussions_trending
# ---------------------------------------------------------------------------

def test_discussions_trending(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussions_trending"]()
        assert "Trending Discussions" in result
        assert "How to win Titanic" in result


def test_discussions_trending_with_source(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussions_trending"](source_type="dataset")
        assert "dataset" in result


def test_discussions_trending_invalid_source(mcp):
    result = mcp.tools["discussions_trending"](source_type="bad_type")
    assert "Invalid source_type" in result


def test_discussions_trending_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussions_trending"]()
        assert "No trending discussions found." in result


# ---------------------------------------------------------------------------
# discussions_my
# ---------------------------------------------------------------------------

def test_discussions_my(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        result = mcp.tools["discussions_my"]()
        assert "My Discussions" in result
        assert "How to win Titanic" in result


def test_discussions_my_empty(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = []
        result = mcp.tools["discussions_my"]()
        assert "No discussions found for your account." in result


def test_discussions_my_passes_list_type(mcp):
    with patch("kaggle_mcp.discussions._search_via_sdk") as mock_search:
        mock_search.return_value = [_SAMPLE_DOC]
        mcp.tools["discussions_my"](page_size=5)
        mock_search.assert_called_once_with(list_type="your_work", page_size=5)
