"""
Tests for memo CRUD APIs.
"""
import pytest
from fastapi import status


class TestListMemos:
    """Test list memos functionality."""
    
    def test_list_memos_authenticated(self, client, authenticated_headers, test_memo_data):
        """Test listing memos for authenticated user."""
        # Create a memo first
        create_response = client.post(
            "/api/v1/memos",
            json=test_memo_data,
            headers=authenticated_headers
        )
        
        # List memos
        response = client.get(
            "/api/v1/memos",
            headers=authenticated_headers
        )
        
        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert isinstance(data, list)
        if authenticated_headers and len(data) > 0:
            assert "content" in data[0]
            assert "id" in data[0]
    
    def test_list_memos_anonymous(self, client):
        """Test listing public memos for anonymous user."""
        response = client.get("/api/v1/memos")
        
        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert isinstance(data, list)
        # Should only see PUBLIC memos
        for memo in data:
            assert memo.get("visibility") == "PUBLIC"
    
    def test_list_memos_filter_by_tag(self, client, authenticated_headers, test_memo_data):
        """Test filtering memos by tag."""
        # Create memo with tag
        client.post(
            "/api/v1/memos",
            json={**test_memo_data, "tags": ["test-tag"]},
            headers=authenticated_headers
        )
        
        # Filter by tag
        response = client.get(
            "/api/v1/memos?tag=test-tag",
            headers=authenticated_headers
        )
        
        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        for memo in data:
            assert "test-tag" in memo.get("tags", [])
    
    def test_list_memos_filter_by_date(self, client, authenticated_headers, test_memo_data):
        """Test filtering memos by date range."""
        response = client.get(
            "/api/v1/memos?start_date=2026-01-01&end_date=2026-01-31",
            headers=authenticated_headers
        )
        
        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert isinstance(data, list)


class TestCreateMemo:
    """Test create memo functionality."""
    
    def test_create_memo_valid(self, client, authenticated_headers, test_memo_data):
        """Test creating memo with valid data."""
        response = client.post(
            "/api/v1/memos",
            json=test_memo_data,
            headers=authenticated_headers
        )
        
        if authenticated_headers:
            assert response.status_code in [status.HTTP_200_OK, status.HTTP_201_CREATED]
            data = response.json()
            assert data["content"] == test_memo_data["content"]
            assert "id" in data
            assert "uid" in data
        else:
            assert response.status_code == status.HTTP_401_UNAUTHORIZED
    
    def test_create_memo_missing_content(self, client, authenticated_headers):
        """Test creating memo without content."""
        response = client.post(
            "/api/v1/memos",
            json={"visibility": "PUBLIC"},
            headers=authenticated_headers
        )
        
        if authenticated_headers:
            assert response.status_code == status.HTTP_400_BAD_REQUEST


class TestGetMemo:
    """Test get memo functionality."""
    
    def test_get_own_memo(self, client, authenticated_headers, test_memo_data):
        """Test getting own memo."""
        # Create memo
        create_response = client.post(
            "/api/v1/memos",
            json=test_memo_data,
            headers=authenticated_headers
        )
        
        if create_response.status_code in [200, 201]:
            memo_id = create_response.json().get("id") or create_response.json().get("uid")
            
            # Get memo
            response = client.get(
                f"/api/v1/memos/{memo_id}",
                headers=authenticated_headers
            )
            
            assert response.status_code == status.HTTP_200_OK
            data = response.json()
            assert data["content"] == test_memo_data["content"]
    
    def test_get_public_memo(self, client, test_memo_data, authenticated_headers):
        """Test getting PUBLIC memo (anyone can access)."""
        # Create PUBLIC memo
        create_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PUBLIC"},
            headers=authenticated_headers
        )
        
        if create_response.status_code in [200, 201]:
            memo_id = create_response.json().get("id") or create_response.json().get("uid")
            
            # Get as anonymous user
            response = client.get(f"/api/v1/memos/{memo_id}")
            
            assert response.status_code == status.HTTP_200_OK
    
    def test_get_private_memo_denied(self, client, test_memo_data, authenticated_headers):
        """Test getting PRIVATE memo (non-owner denied)."""
        # This test requires two users, so we'll test access denied scenario
        # Create PRIVATE memo
        create_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PRIVATE"},
            headers=authenticated_headers
        )
        
        if create_response.status_code in [200, 201]:
            memo_id = create_response.json().get("id") or create_response.json().get("uid")
            
            # Try to get as anonymous (should be denied)
            response = client.get(f"/api/v1/memos/{memo_id}")
            
            assert response.status_code in [status.HTTP_403_FORBIDDEN, status.HTTP_404_NOT_FOUND]


class TestUpdateMemo:
    """Test update memo functionality."""
    
    def test_update_own_memo(self, client, authenticated_headers, test_memo_data):
        """Test updating own memo."""
        # Create memo
        create_response = client.post(
            "/api/v1/memos",
            json=test_memo_data,
            headers=authenticated_headers
        )
        
        if create_response.status_code in [200, 201]:
            memo_id = create_response.json().get("id") or create_response.json().get("uid")
            
            # Update memo
            response = client.patch(
                f"/api/v1/memos/{memo_id}",
                json={"content": "Updated content"},
                headers=authenticated_headers
            )
            
            assert response.status_code == status.HTTP_200_OK
            data = response.json()
            assert data["content"] == "Updated content"


class TestDeleteMemo:
    """Test delete memo functionality."""
    
    def test_delete_own_memo(self, client, authenticated_headers, test_memo_data):
        """Test deleting own memo."""
        # Create memo
        create_response = client.post(
            "/api/v1/memos",
            json=test_memo_data,
            headers=authenticated_headers
        )
        
        if create_response.status_code in [200, 201]:
            memo_id = create_response.json().get("id") or create_response.json().get("uid")
            
            # Delete memo
            response = client.delete(
                f"/api/v1/memos/{memo_id}",
                headers=authenticated_headers
            )
            
            assert response.status_code in [status.HTTP_200_OK, status.HTTP_204_NO_CONTENT]
            
            # Verify memo is deleted (or archived)
            get_response = client.get(
                f"/api/v1/memos/{memo_id}",
                headers=authenticated_headers
            )
            # Should return 404 or memo with row_status=ARCHIVED
            assert get_response.status_code in [
                status.HTTP_404_NOT_FOUND,
                status.HTTP_200_OK  # If soft delete
            ]

