"""
Tests for web/services/resource_service.py

Tests cover:
- get_resources_for_research function
- add_resource function
- delete_resource function
"""

import pytest
from unittest.mock import Mock, patch, MagicMock


class TestGetResourcesForResearch:
    """Tests for get_resources_for_research function."""

    def test_get_resources_success(self):
        """Test successful resource retrieval."""
        from local_deep_research.web.services.resource_service import (
            get_resources_for_research,
        )

        mock_resource = Mock()
        mock_resource.id = 1
        mock_resource.research_id = "test-uuid"
        mock_resource.title = "Test Resource"
        mock_resource.url = "https://example.com"
        mock_resource.content_preview = "Preview text..."
        mock_resource.source_type = "web"
        mock_resource.resource_metadata = {"author": "Test"}

        mock_session = MagicMock()
        mock_query = mock_session.query.return_value
        mock_query.filter_by.return_value.order_by.return_value.all.return_value = [
            mock_resource
        ]

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__.return_value = mock_session

            result = get_resources_for_research("test-uuid")

            assert len(result) == 1
            assert result[0]["id"] == 1
            assert result[0]["title"] == "Test Resource"
            assert result[0]["url"] == "https://example.com"
            assert result[0]["metadata"] == {"author": "Test"}

    def test_get_resources_empty(self):
        """Test getting resources when none exist."""
        from local_deep_research.web.services.resource_service import (
            get_resources_for_research,
        )

        mock_session = MagicMock()
        mock_query = mock_session.query.return_value
        mock_query.filter_by.return_value.order_by.return_value.all.return_value = []

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__.return_value = mock_session

            result = get_resources_for_research("nonexistent-uuid")

            assert result == []

    def test_get_resources_null_metadata(self):
        """Test resources with null metadata."""
        from local_deep_research.web.services.resource_service import (
            get_resources_for_research,
        )

        mock_resource = Mock()
        mock_resource.id = 1
        mock_resource.research_id = "test-uuid"
        mock_resource.title = "Test"
        mock_resource.url = "https://example.com"
        mock_resource.content_preview = None
        mock_resource.source_type = "web"
        mock_resource.resource_metadata = None

        mock_session = MagicMock()
        mock_query = mock_session.query.return_value
        mock_query.filter_by.return_value.order_by.return_value.all.return_value = [
            mock_resource
        ]

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__.return_value = mock_session

            result = get_resources_for_research("test-uuid")

            assert result[0]["metadata"] == {}

    def test_get_resources_exception(self):
        """Test exception handling in get_resources."""
        from local_deep_research.web.services.resource_service import (
            get_resources_for_research,
        )

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__.side_effect = Exception(
                "DB Error"
            )

            with pytest.raises(Exception):
                get_resources_for_research("test-uuid")


class TestAddResource:
    """Tests for add_resource function."""

    def test_add_resource_minimal(self):
        """Test adding resource with minimal parameters."""
        from local_deep_research.web.services.resource_service import (
            add_resource,
        )

        mock_session = MagicMock()
        mock_resource = Mock()

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            with patch(
                "local_deep_research.web.services.resource_service.ResearchResource"
            ) as mock_resource_class:
                mock_get_session.return_value.__enter__.return_value = (
                    mock_session
                )
                mock_resource_class.return_value = mock_resource

                add_resource(
                    research_id="test-uuid",
                    title="Test Resource",
                    url="https://example.com",
                )

                mock_session.add.assert_called_once_with(mock_resource)
                mock_session.commit.assert_called_once()

    def test_add_resource_full(self):
        """Test adding resource with all parameters."""
        from local_deep_research.web.services.resource_service import (
            add_resource,
        )

        mock_session = MagicMock()

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            with patch(
                "local_deep_research.web.services.resource_service.ResearchResource"
            ) as mock_resource_class:
                mock_get_session.return_value.__enter__.return_value = (
                    mock_session
                )
                mock_resource = Mock()
                mock_resource_class.return_value = mock_resource

                add_resource(
                    research_id="test-uuid",
                    title="Full Resource",
                    url="https://example.com/full",
                    content_preview="Preview content...",
                    source_type="pdf",
                    metadata={"pages": 10},
                )

                mock_resource_class.assert_called_once()
                call_kwargs = mock_resource_class.call_args[1]
                assert call_kwargs["research_id"] == "test-uuid"
                assert call_kwargs["title"] == "Full Resource"
                assert call_kwargs["source_type"] == "pdf"
                assert call_kwargs["resource_metadata"] == {"pages": 10}

    def test_add_resource_exception(self):
        """Test exception handling in add_resource."""
        from local_deep_research.web.services.resource_service import (
            add_resource,
        )

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__.side_effect = Exception(
                "DB Error"
            )

            with pytest.raises(Exception):
                add_resource("uuid", "title", "url")


class TestDeleteResource:
    """Tests for delete_resource function."""

    def test_delete_resource_success(self):
        """Test successful resource deletion."""
        from local_deep_research.web.services.resource_service import (
            delete_resource,
        )

        mock_session = MagicMock()
        mock_resource = Mock()
        mock_query = mock_session.query.return_value
        mock_query.filter_by.return_value.first.return_value = mock_resource

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__.return_value = mock_session

            result = delete_resource(123)

            assert result is True
            mock_session.delete.assert_called_once_with(mock_resource)
            mock_session.commit.assert_called_once()

    def test_delete_resource_not_found(self):
        """Test deletion of non-existent resource."""
        from local_deep_research.web.services.resource_service import (
            delete_resource,
        )

        mock_session = MagicMock()
        mock_query = mock_session.query.return_value
        mock_query.filter_by.return_value.first.return_value = None

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__.return_value = mock_session

            with pytest.raises(ValueError) as exc_info:
                delete_resource(999)

            assert "not found" in str(exc_info.value)

    def test_delete_resource_exception(self):
        """Test exception handling in delete_resource."""
        from local_deep_research.web.services.resource_service import (
            delete_resource,
        )

        with patch(
            "local_deep_research.web.services.resource_service.get_user_db_session"
        ) as mock_get_session:
            mock_session = MagicMock()
            mock_get_session.return_value.__enter__.return_value = mock_session
            mock_session.query.side_effect = Exception("DB Error")

            with pytest.raises(Exception):
                delete_resource(123)
