"""
Tests for comment APIs.
"""
import pytest
from fastapi import status


class TestCreateComment:
    """Test create comment functionality."""
    
    def test_create_comment_public_memo(self, client, authenticated_headers, test_memo_data):
        """Test creating comment for PUBLIC memo."""
        # Create PUBLIC memo
        memo_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PUBLIC"},
            headers=authenticated_headers
        )
        
        if memo_response.status_code in [200, 201] and authenticated_headers:
            memo_id = memo_response.json().get("id") or memo_response.json().get("uid")
            
            # Create comment
            comment_response = client.post(
                f"/api/v1/memos/{memo_id}/comments",
                json={"content": "This is a test comment", "visibility": "PUBLIC"},
                headers=authenticated_headers
            )
            
            assert comment_response.status_code in [status.HTTP_200_OK, status.HTTP_201_CREATED]
            comment_data = comment_response.json()
            assert comment_data["content"] == "This is a test comment"
            assert "id" in comment_data
            assert "parent" in comment_data or comment_data.get("parent") is not None
    
    def test_create_comment_protected_memo(self, client, authenticated_headers, test_memo_data):
        """Test creating comment for PROTECTED memo (logged-in only)."""
        # Create PROTECTED memo
        memo_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PROTECTED"},
            headers=authenticated_headers
        )
        
        if memo_response.status_code in [200, 201] and authenticated_headers:
            memo_id = memo_response.json().get("id") or memo_response.json().get("uid")
            
            # Create comment (should work for logged-in user)
            comment_response = client.post(
                f"/api/v1/memos/{memo_id}/comments",
                json={"content": "Test comment", "visibility": "PUBLIC"},
                headers=authenticated_headers
            )
            
            assert comment_response.status_code in [status.HTTP_200_OK, status.HTTP_201_CREATED]
    
    def test_create_comment_private_memo_denied(self, client, authenticated_headers, test_memo_data):
        """Test creating comment for PRIVATE memo (non-owner denied)."""
        # Create PRIVATE memo
        memo_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PRIVATE"},
            headers=authenticated_headers
        )
        
        if memo_response.status_code in [200, 201] and authenticated_headers:
            memo_id = memo_response.json().get("id") or memo_response.json().get("uid")
            
            # Try to create comment as anonymous (should be denied)
            comment_response = client.post(
                f"/api/v1/memos/{memo_id}/comments",
                json={"content": "Test comment", "visibility": "PUBLIC"}
            )
            
            assert comment_response.status_code in [
                status.HTTP_403_FORBIDDEN,
                status.HTTP_404_NOT_FOUND
            ]


class TestListComments:
    """Test list comments functionality."""
    
    def test_list_comments_empty(self, client, authenticated_headers, test_memo_data):
        """Test listing comments when no comments exist."""
        # Create memo
        memo_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PUBLIC"},
            headers=authenticated_headers
        )
        
        if memo_response.status_code in [200, 201]:
            memo_id = memo_response.json().get("id") or memo_response.json().get("uid")
            
            # List comments
            response = client.get(f"/api/v1/memos/{memo_id}/comments")
            
            assert response.status_code == status.HTTP_200_OK
            data = response.json()
            assert "memos" in data
            assert len(data["memos"]) == 0
            assert data.get("totalSize", 0) == 0
    
    def test_list_comments_with_comments(self, client, authenticated_headers, test_memo_data):
        """Test listing comments when comments exist."""
        # Create PUBLIC memo
        memo_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PUBLIC"},
            headers=authenticated_headers
        )
        
        if memo_response.status_code in [200, 201] and authenticated_headers:
            memo_id = memo_response.json().get("id") or memo_response.json().get("uid")
            
            # Create comment
            client.post(
                f"/api/v1/memos/{memo_id}/comments",
                json={"content": "Comment 1", "visibility": "PUBLIC"},
                headers=authenticated_headers
            )
            
            # List comments
            response = client.get(f"/api/v1/memos/{memo_id}/comments")
            
            assert response.status_code == status.HTTP_200_OK
            data = response.json()
            assert "memos" in data
            assert len(data["memos"]) >= 1
            assert data["memos"][0]["content"] == "Comment 1"
    
    def test_list_comments_visibility_filter(self, client, authenticated_headers, test_memo_data):
        """Test comment visibility filtering."""
        # Create PUBLIC memo
        memo_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PUBLIC"},
            headers=authenticated_headers
        )
        
        if memo_response.status_code in [200, 201] and authenticated_headers:
            memo_id = memo_response.json().get("id") or memo_response.json().get("uid")
            
            # Create PUBLIC comment
            client.post(
                f"/api/v1/memos/{memo_id}/comments",
                json={"content": "Public comment", "visibility": "PUBLIC"},
                headers=authenticated_headers
            )
            
            # Create PROTECTED comment
            client.post(
                f"/api/v1/memos/{memo_id}/comments",
                json={"content": "Protected comment", "visibility": "PROTECTED"},
                headers=authenticated_headers
            )
            
            # List as anonymous (should only see PUBLIC)
            response = client.get(f"/api/v1/memos/{memo_id}/comments")
            
            assert response.status_code == status.HTTP_200_OK
            data = response.json()
            for comment in data["memos"]:
                assert comment.get("visibility") == "PUBLIC"
            
            # List as logged-in (should see PUBLIC + PROTECTED)
            if authenticated_headers:
                response = client.get(
                    f"/api/v1/memos/{memo_id}/comments",
                    headers=authenticated_headers
                )
                
                assert response.status_code == status.HTTP_200_OK
                data = response.json()
                visibilities = [c.get("visibility") for c in data["memos"]]
                assert "PUBLIC" in visibilities
                assert "PROTECTED" in visibilities
    
    def test_list_comments_sorted_oldest_first(self, client, authenticated_headers, test_memo_data):
        """Test comments are sorted by create_time ASC (oldest first)."""
        # Create PUBLIC memo
        memo_response = client.post(
            "/api/v1/memos",
            json={**test_memo_data, "visibility": "PUBLIC"},
            headers=authenticated_headers
        )
        
        if memo_response.status_code in [200, 201] and authenticated_headers:
            memo_id = memo_response.json().get("id") or memo_response.json().get("uid")
            
            # Create multiple comments
            client.post(
                f"/api/v1/memos/{memo_id}/comments",
                json={"content": "First comment", "visibility": "PUBLIC"},
                headers=authenticated_headers
            )
            
            import time
            time.sleep(0.1)  # Small delay to ensure different timestamps
            
            client.post(
                f"/api/v1/memos/{memo_id}/comments",
                json={"content": "Second comment", "visibility": "PUBLIC"},
                headers=authenticated_headers
            )
            
            # List comments
            response = client.get(f"/api/v1/memos/{memo_id}/comments")
            
            assert response.status_code == status.HTTP_200_OK
            data = response.json()
            assert len(data["memos"]) >= 2
            
            # Verify order (oldest first)
            comments = data["memos"]
            for i in range(len(comments) - 1):
                current_time = comments[i].get("create_time", "")
                next_time = comments[i + 1].get("create_time", "")
                if current_time and next_time:
                    assert current_time <= next_time

