"""Tests for competition tools."""

from unittest.mock import MagicMock, patch

import pytest

from tests.conftest import MockMCP


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


def _client(mcp_fixture):
    """Return a fresh mock client and patch get_client."""
    return patch("kaggle_mcp.competitions.get_client")


# ---------------------------------------------------------------------------
# competitions_list
# ---------------------------------------------------------------------------

def test_competitions_list_returns_formatted(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        comp = MagicMock()
        comp.title = "Titanic"
        comp.ref = "titanic"
        comp.category = "Getting Started"
        comp.deadline = "2024-12-31"
        comp.team_count = 15000
        mock_gc.return_value.competitions.competition_api_client.list_competitions.return_value.competitions = [comp]

        result = mcp.tools["competitions_list"]()
        assert "Titanic" in result
        assert "titanic" in result
        assert "Getting Started" in result


def test_competitions_list_empty(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        mock_gc.return_value.competitions.competition_api_client.list_competitions.return_value.competitions = []
        result = mcp.tools["competitions_list"]()
        assert result == "No competitions found."


# ---------------------------------------------------------------------------
# competition_files
# ---------------------------------------------------------------------------

def test_competition_files_returns_list(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        f = MagicMock()
        f.name = "train.csv"
        f.total_bytes = 1024
        mock_gc.return_value.competitions.competition_api_client.list_data_files.return_value.files = [f]

        result = mcp.tools["competition_files"]("titanic")
        assert "train.csv" in result


def test_competition_files_empty(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        mock_gc.return_value.competitions.competition_api_client.list_data_files.return_value.files = []
        result = mcp.tools["competition_files"]("titanic")
        assert result == "No files found."


# ---------------------------------------------------------------------------
# competition_download
# ---------------------------------------------------------------------------

def test_competition_download_all_files(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        mock_gc.return_value.competitions.competition_api_client.download_data_files.return_value.url = "https://example.com/all.zip"
        result = mcp.tools["competition_download"]("titanic")
        assert "https://example.com/all.zip" in result


def test_competition_download_single_file(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        mock_gc.return_value.competitions.competition_api_client.download_data_file.return_value.url = "https://example.com/train.csv"
        result = mcp.tools["competition_download"]("titanic", "train.csv")
        assert "https://example.com/train.csv" in result


# ---------------------------------------------------------------------------
# competition_submit
# ---------------------------------------------------------------------------

def test_competition_submit(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        resp = MagicMock()
        resp.to_dict.return_value = {"id": 42, "status": "pending"}
        mock_gc.return_value.competitions.competition_api_client.create_submission.return_value = resp

        result = mcp.tools["competition_submit"]("titanic", "token123", "my submission")
        assert "42" in result or "pending" in result


# ---------------------------------------------------------------------------
# competition_submissions
# ---------------------------------------------------------------------------

def test_competition_submissions_returns_list(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        s = MagicMock()
        s.date = "2024-01-01"
        s.public_score = "0.77"
        s.status = "complete"
        s.description = "test run"
        mock_gc.return_value.competitions.competition_api_client.list_submissions.return_value.submissions = [s]

        result = mcp.tools["competition_submissions"]("titanic")
        assert "0.77" in result
        assert "complete" in result


def test_competition_submissions_empty(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        mock_gc.return_value.competitions.competition_api_client.list_submissions.return_value.submissions = []
        result = mcp.tools["competition_submissions"]("titanic")
        assert result == "No submissions found."


# ---------------------------------------------------------------------------
# competition_leaderboard
# ---------------------------------------------------------------------------

def test_competition_leaderboard_top20(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        s = MagicMock()
        s.team_name = "TeamAlpha"
        s.score = "0.99"
        mock_gc.return_value.competitions.competition_api_client.get_leaderboard.return_value.submissions = [s]

        result = mcp.tools["competition_leaderboard"]("titanic")
        assert "TeamAlpha" in result
        assert "0.99" in result


def test_competition_leaderboard_empty(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        mock_gc.return_value.competitions.competition_api_client.get_leaderboard.return_value.submissions = []
        result = mcp.tools["competition_leaderboard"]("titanic")
        assert result == "No leaderboard data."


# ---------------------------------------------------------------------------
# competition_get
# ---------------------------------------------------------------------------

def test_competition_get_returns_details(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        c = MagicMock()
        c.title = "Titanic"
        c.ref = "titanic"
        c.url = "https://kaggle.com/c/titanic"
        c.category = "Getting Started"
        c.reward = "Knowledge"
        c.deadline = "2024-12-31"
        c.team_count = 15000
        c.evaluation_metric = "Accuracy"
        c.max_daily_submissions = 10
        c.max_team_size = 5
        c.is_kernels_submissions_only = False
        c.description = "Predict survival"
        mock_gc.return_value.competitions.competition_api_client.get_competition.return_value = c

        result = mcp.tools["competition_get"]("titanic")
        assert "Titanic" in result
        assert "Accuracy" in result


def test_competition_get_error(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        client = mock_gc.return_value
        client.competitions.competition_api_client.get_competition.side_effect = Exception("not found")
        client.competitions.competition_api_client.list_competitions.side_effect = Exception("also failed")
        result = mcp.tools["competition_get"]("bad-slug")
        assert "Error" in result


# ---------------------------------------------------------------------------
# competition_data_summary
# ---------------------------------------------------------------------------

def test_competition_data_summary(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        resp = MagicMock()
        resp.to_dict.return_value = {"total_bytes": 1024}
        mock_gc.return_value.competitions.competition_api_client.get_competition_data_files_summary.return_value = resp

        result = mcp.tools["competition_data_summary"]("titanic")
        assert "1024" in result


# ---------------------------------------------------------------------------
# competition_get_submission
# ---------------------------------------------------------------------------

def test_competition_get_submission(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        resp = MagicMock()
        resp.to_dict.return_value = {"id": 99, "score": "0.88"}
        mock_gc.return_value.competitions.competition_api_client.get_submission.return_value = resp

        result = mcp.tools["competition_get_submission"]("titanic", 99)
        assert "99" in result or "0.88" in result


# ---------------------------------------------------------------------------
# competition_leaderboard_download
# ---------------------------------------------------------------------------

def test_competition_leaderboard_download(mcp):
    with patch("kaggle_mcp.competitions.get_client") as mock_gc:
        mock_gc.return_value.competitions.competition_api_client.download_leaderboard.return_value.url = "https://example.com/lb.csv"
        result = mcp.tools["competition_leaderboard_download"]("titanic")
        assert "https://example.com/lb.csv" in result
