"""Tests for main module."""

import logging
import sys
from unittest.mock import MagicMock, patch

# Need to mock the environment variables before importing main.
with patch.dict(
    "os.environ",
    {"JIRA_API_TOKEN": "test-token", "JIRA_AUTH_TYPE": "basic"},
):
    from src.main import (
        add_comment_tool,
        assign_to_me_tool,
        create_ticket_tool,
        get_ticket_tool,
        list_tickets_tool,
        move_ticket_tool,
        open_ticket_in_browser_tool,
        setup_logging,
        update_ticket_description_tool,
    )


class TestSetupLogging:
    """Tests for setup_logging function."""

    def test_setup_logging_default_level(self) -> None:
        """Test setup_logging with default (INFO) level."""
        with patch("logging.basicConfig") as mock_basic_config:
            setup_logging(debug=False)
            mock_basic_config.assert_called_once()
            call_kwargs = mock_basic_config.call_args[1]
            assert call_kwargs["level"] == logging.INFO

    def test_setup_logging_debug_level(self) -> None:
        """Test setup_logging with DEBUG level."""
        with patch("logging.basicConfig") as mock_basic_config:
            setup_logging(debug=True)
            mock_basic_config.assert_called_once()
            call_kwargs = mock_basic_config.call_args[1]
            assert call_kwargs["level"] == logging.DEBUG

    def test_setup_logging_uses_stderr(self) -> None:
        """Test setup_logging uses stderr for output."""
        with patch("logging.basicConfig") as mock_basic_config:
            setup_logging()
            call_kwargs = mock_basic_config.call_args[1]
            assert call_kwargs["stream"] == sys.stderr


class TestListTicketsTool:
    """Tests for list_tickets_tool function."""

    @patch("src.main.list_tickets")
    def test_list_tickets_success(self, mock_list_tickets: MagicMock) -> None:
        """Test list_tickets_tool with results."""
        from src.models.jira_tickets import JiraTicket

        mock_list_tickets.return_value = [
            JiraTicket(
                key="TEST-1",
                summary="Test ticket",
                status="Open",
                priority="High",
                type="Bug",
                assignee="John Doe",
            ),
            JiraTicket(
                key="TEST-2",
                summary="Another ticket",
                status="Done",
                priority="Low",
                type="Task",
            ),
        ]

        result = list_tickets_tool()

        assert "TEST-1" in result
        assert "Test ticket" in result
        assert "TEST-2" in result
        assert "John Doe" in result

    @patch("src.main.list_tickets")
    def test_list_tickets_no_results(
        self, mock_list_tickets: MagicMock
    ) -> None:
        """Test list_tickets_tool with no results."""
        mock_list_tickets.return_value = []

        result = list_tickets_tool()

        assert result == "No tickets found."

    @patch("src.main.list_tickets")
    def test_list_tickets_error(self, mock_list_tickets: MagicMock) -> None:
        """Test list_tickets_tool with error."""
        mock_list_tickets.side_effect = ValueError("Test error")

        result = list_tickets_tool()

        assert "Error listing tickets" in result
        assert "Test error" in result

    @patch("src.main.list_tickets")
    def test_list_tickets_with_filters(
        self, mock_list_tickets: MagicMock
    ) -> None:
        """Test list_tickets_tool passes filters correctly."""
        mock_list_tickets.return_value = []

        list_tickets_tool(
            jql="project = TEST",
            limit=10,
            assigned_to_me=True,
            status="Open",
        )

        mock_list_tickets.assert_called_once_with(
            jql="project = TEST",
            limit=10,
            assigned_to_me=True,
            unassigned=None,
            status="Open",
            project=None,
            created_recently=None,
            updated_recently=None,
            order_by=None,
            order_direction=None,
        )


class TestGetTicketTool:
    """Tests for get_ticket_tool function."""

    @patch("src.main.get_ticket")
    def test_get_ticket_success(self, mock_get_ticket: MagicMock) -> None:
        """Test get_ticket_tool with valid ticket."""
        from src.models.jira_tickets import JiraComment, JiraTicketDetail

        mock_get_ticket.return_value = JiraTicketDetail(
            key="TEST-123",
            summary="Test summary",
            status="Open",
            priority="High",
            type="Bug",
            assignee="John Doe",
            reporter="Jane Smith",
            created="2024-01-10T09:00:00.000+0000",
            updated="2024-01-15T10:30:00.000+0000",
            description="Test description",
            comments=[
                JiraComment(
                    author="John Doe",
                    created="2024-01-15T10:30:00.000+0000",
                    body="Test comment",
                )
            ],
        )

        result = get_ticket_tool("TEST-123")

        assert "TEST-123" in result
        assert "Test summary" in result
        assert "Open" in result
        assert "John Doe" in result
        assert "Test description" in result
        assert "Test comment" in result

    @patch("src.main.get_ticket")
    def test_get_ticket_no_description(
        self, mock_get_ticket: MagicMock
    ) -> None:
        """Test get_ticket_tool with no description."""
        from src.models.jira_tickets import JiraTicketDetail

        mock_get_ticket.return_value = JiraTicketDetail(
            key="TEST-123",
            summary="Test",
            status="Open",
            priority="High",
            type="Bug",
            description=None,
        )

        result = get_ticket_tool("TEST-123")

        assert "No description provided" in result

    @patch("src.main.get_ticket")
    def test_get_ticket_no_comments(self, mock_get_ticket: MagicMock) -> None:
        """Test get_ticket_tool with no comments."""
        from src.models.jira_tickets import JiraTicketDetail

        mock_get_ticket.return_value = JiraTicketDetail(
            key="TEST-123",
            summary="Test",
            status="Open",
            priority="High",
            type="Bug",
            comments=[],
        )

        result = get_ticket_tool("TEST-123")

        assert "No comments" in result

    @patch("src.main.get_ticket")
    def test_get_ticket_error(self, mock_get_ticket: MagicMock) -> None:
        """Test get_ticket_tool with error."""
        mock_get_ticket.side_effect = ValueError("Ticket not found")

        result = get_ticket_tool("INVALID-123")

        assert "Error getting ticket" in result
        assert "INVALID-123" in result


class TestCreateTicketTool:
    """Tests for create_ticket_tool function."""

    @patch("src.main.create_ticket")
    def test_create_ticket_success(self, mock_create_ticket: MagicMock) -> None:
        """Test create_ticket_tool success."""
        from src.models.jira_actions import CreateTicketResult

        mock_create_ticket.return_value = CreateTicketResult(
            success=True,
            ticket_key="TEST-456",
            ticket_url="https://jira.example.com/browse/TEST-456",
        )

        result = create_ticket_tool(
            project="TEST",
            issue_type="Bug",
            summary="New bug",
        )

        assert "Successfully created" in result
        assert "TEST-456" in result

    @patch("src.main.create_ticket")
    def test_create_ticket_failure(self, mock_create_ticket: MagicMock) -> None:
        """Test create_ticket_tool failure."""
        from src.models.jira_actions import CreateTicketResult

        mock_create_ticket.return_value = CreateTicketResult(
            success=False,
            error="Project not found",
        )

        result = create_ticket_tool(
            project="INVALID",
            issue_type="Bug",
            summary="Test",
        )

        assert "Failed to create ticket" in result
        assert "Project not found" in result

    @patch("src.main.create_ticket")
    def test_create_ticket_exception(
        self, mock_create_ticket: MagicMock
    ) -> None:
        """Test create_ticket_tool with exception."""
        mock_create_ticket.side_effect = Exception("Network error")

        result = create_ticket_tool(
            project="TEST",
            issue_type="Bug",
            summary="Test",
        )

        assert "Error creating ticket" in result


class TestMoveTicketTool:
    """Tests for move_ticket_tool function."""

    @patch("src.main.move_ticket")
    def test_move_ticket_success(self, mock_move_ticket: MagicMock) -> None:
        """Test move_ticket_tool success."""
        from src.models.jira_actions import MoveTicketResult

        mock_move_ticket.return_value = MoveTicketResult(
            success=True,
            ticket_key="TEST-123",
            previous_status="Open",
            new_status="In Progress",
            message="Successfully moved TEST-123 from Open to In Progress",
        )

        result = move_ticket_tool("TEST-123", "In Progress")

        assert "Successfully moved" in result

    @patch("src.main.move_ticket")
    def test_move_ticket_error(self, mock_move_ticket: MagicMock) -> None:
        """Test move_ticket_tool with error."""
        mock_move_ticket.side_effect = ValueError("Invalid transition")

        result = move_ticket_tool("TEST-123", "Invalid Status")

        assert "Error moving ticket" in result


class TestAddCommentTool:
    """Tests for add_comment_tool function."""

    @patch("src.main.add_comment")
    def test_add_comment_success(self, mock_add_comment: MagicMock) -> None:
        """Test add_comment_tool success."""
        from src.models.jira_actions import AddCommentResult

        mock_add_comment.return_value = AddCommentResult(
            success=True,
            ticket_key="TEST-123",
            message="Successfully added comment to TEST-123",
        )

        result = add_comment_tool("TEST-123", "Test comment")

        assert "Successfully added" in result

    @patch("src.main.add_comment")
    def test_add_comment_error(self, mock_add_comment: MagicMock) -> None:
        """Test add_comment_tool with error."""
        mock_add_comment.side_effect = ValueError("Permission denied")

        result = add_comment_tool("TEST-123", "Comment")

        assert "Error adding comment" in result


class TestAssignToMeTool:
    """Tests for assign_to_me_tool function."""

    @patch("src.main.assign_to_me")
    def test_assign_to_me_success(self, mock_assign_to_me: MagicMock) -> None:
        """Test assign_to_me_tool success."""
        from src.models.jira_actions import AssignToMeResult

        mock_assign_to_me.return_value = AssignToMeResult(
            success=True,
            ticket_key="TEST-123",
            assignee="john.doe@example.com",
            message="Successfully assigned TEST-123 to john.doe@example.com",
        )

        result = assign_to_me_tool("TEST-123")

        assert "Successfully assigned" in result

    @patch("src.main.assign_to_me")
    def test_assign_to_me_error(self, mock_assign_to_me: MagicMock) -> None:
        """Test assign_to_me_tool with error."""
        mock_assign_to_me.side_effect = ValueError("Auth error")

        result = assign_to_me_tool("TEST-123")

        assert "Error assigning ticket" in result


class TestOpenTicketInBrowserTool:
    """Tests for open_ticket_in_browser_tool function."""

    @patch("src.main.open_ticket_in_browser")
    def test_open_ticket_success(self, mock_open_ticket: MagicMock) -> None:
        """Test open_ticket_in_browser_tool success."""
        mock_open_ticket.return_value = (
            "Successfully opened ticket TEST-123 in browser"
        )

        result = open_ticket_in_browser_tool("TEST-123")

        assert "Successfully opened" in result

    @patch("src.main.open_ticket_in_browser")
    def test_open_ticket_error(self, mock_open_ticket: MagicMock) -> None:
        """Test open_ticket_in_browser_tool with error."""
        mock_open_ticket.side_effect = ValueError("Browser error")

        result = open_ticket_in_browser_tool("TEST-123")

        assert "Error opening ticket" in result


class TestUpdateTicketDescriptionTool:
    """Tests for update_ticket_description_tool function."""

    @patch("src.main.update_ticket_description")
    def test_update_description_success(
        self, mock_update_description: MagicMock
    ) -> None:
        """Test update_ticket_description_tool success."""
        from src.models.jira_actions import UpdateDescriptionResult

        mock_update_description.return_value = UpdateDescriptionResult(
            success=True,
            ticket_key="TEST-123",
            message="Successfully updated description for TEST-123",
        )

        result = update_ticket_description_tool("TEST-123", "New description")

        assert "Successfully updated" in result

    @patch("src.main.update_ticket_description")
    def test_update_description_error(
        self, mock_update_description: MagicMock
    ) -> None:
        """Test update_ticket_description_tool with error."""
        mock_update_description.side_effect = ValueError("Permission denied")

        result = update_ticket_description_tool("TEST-123", "Description")

        assert "Error updating description" in result
