# allow: no-sut-import — black-box HTTP test; drives real routes through the Flask test client
"""
Tests for chat end-to-end flows.

These tests verify complete workflows through the chat system,
from session creation through message exchange.
"""

import json


class TestChatE2EFlows:
    """End-to-end flow tests for chat feature."""

    def test_full_conversation_flow_create_send_receive(
        self, authenticated_client
    ):
        """Test complete flow: create session -> send message -> get messages."""
        # Step 1: Create session
        create_response = authenticated_client.post(
            "/api/chat/sessions",
            json={"initial_query": "What is machine learning?"},
            content_type="application/json",
        )
        assert create_response.status_code == 200
        create_data = json.loads(create_response.data)
        assert create_data["success"] is True
        session_id = create_data["session_id"]

        # Step 2: Send a message
        send_response = authenticated_client.post(
            f"/api/chat/sessions/{session_id}/messages",
            json={
                "content": "Tell me about neural networks",
                "trigger_research": False,
            },
            content_type="application/json",
        )
        assert send_response.status_code == 200
        send_data = json.loads(send_response.data)
        assert send_data["success"] is True
        message_id = send_data["message_id"]

        # Step 3: Get messages
        get_response = authenticated_client.get(
            f"/api/chat/sessions/{session_id}/messages"
        )
        assert get_response.status_code == 200
        get_data = json.loads(get_response.data)
        assert get_data["success"] is True
        assert len(get_data["messages"]) >= 1

        # Verify our message is in the list
        message_ids = [m["id"] for m in get_data["messages"]]
        assert message_id in message_ids

    def test_multi_turn_conversation_flow(self, authenticated_client):
        """Test multiple messages in a conversation."""
        # Create session
        create_response = authenticated_client.post(
            "/api/chat/sessions",
            json={"initial_query": "Learning about AI"},
            content_type="application/json",
        )
        session_id = json.loads(create_response.data)["session_id"]

        # Send multiple messages
        messages = [
            "What is artificial intelligence?",
            "How does deep learning work?",
            "What are transformers in NLP?",
        ]

        for i, content in enumerate(messages):
            response = authenticated_client.post(
                f"/api/chat/sessions/{session_id}/messages",
                json={"content": content, "trigger_research": False},
                content_type="application/json",
            )
            assert response.status_code == 200

        # Verify all messages are stored
        get_response = authenticated_client.get(
            f"/api/chat/sessions/{session_id}/messages"
        )
        get_data = json.loads(get_response.data)
        assert len(get_data["messages"]) == len(messages)

        # Verify session message count
        session_response = authenticated_client.get(
            f"/api/chat/sessions/{session_id}"
        )
        session_data = json.loads(session_response.data)
        assert session_data["session"]["message_count"] == len(messages)

    def test_session_update_and_archive_flow(self, authenticated_client):
        """Test session update and archive flow."""
        # Create session
        create_response = authenticated_client.post(
            "/api/chat/sessions",
            json={"initial_query": "Test session"},
            content_type="application/json",
        )
        session_id = json.loads(create_response.data)["session_id"]

        # Update title
        update_response = authenticated_client.patch(
            f"/api/chat/sessions/{session_id}",
            json={"title": "Updated Title"},
            content_type="application/json",
        )
        assert update_response.status_code == 200
        update_data = json.loads(update_response.data)
        assert update_data["session"]["title"] == "Updated Title"

        # Archive session
        archive_response = authenticated_client.patch(
            f"/api/chat/sessions/{session_id}",
            json={"status": "archived"},
            content_type="application/json",
        )
        assert archive_response.status_code == 200
        archive_data = json.loads(archive_response.data)
        assert archive_data["session"]["status"] == "archived"

        # Verify archived session not in default list
        list_response = authenticated_client.get(
            "/api/chat/sessions?status=active"
        )
        list_data = json.loads(list_response.data)
        session_ids = [s["id"] for s in list_data["sessions"]]
        assert session_id not in session_ids

        # But appears in archived list
        archived_response = authenticated_client.get(
            "/api/chat/sessions?status=archived"
        )
        archived_data = json.loads(archived_response.data)
        archived_ids = [s["id"] for s in archived_data["sessions"]]
        assert session_id in archived_ids

    def test_concurrent_sessions_isolated(self, authenticated_client):
        """Test that multiple sessions are properly isolated."""
        # Create two sessions
        session1_response = authenticated_client.post(
            "/api/chat/sessions",
            json={"initial_query": "Session 1 topic"},
            content_type="application/json",
        )
        session1_id = json.loads(session1_response.data)["session_id"]

        session2_response = authenticated_client.post(
            "/api/chat/sessions",
            json={"initial_query": "Session 2 topic"},
            content_type="application/json",
        )
        session2_id = json.loads(session2_response.data)["session_id"]

        # Add messages to session 1
        authenticated_client.post(
            f"/api/chat/sessions/{session1_id}/messages",
            json={
                "content": "Message for session 1",
                "trigger_research": False,
            },
            content_type="application/json",
        )
        authenticated_client.post(
            f"/api/chat/sessions/{session1_id}/messages",
            json={
                "content": "Another message for session 1",
                "trigger_research": False,
            },
            content_type="application/json",
        )

        # Add different message to session 2
        authenticated_client.post(
            f"/api/chat/sessions/{session2_id}/messages",
            json={
                "content": "Message for session 2",
                "trigger_research": False,
            },
            content_type="application/json",
        )

        # Verify messages are isolated
        session1_messages = json.loads(
            authenticated_client.get(
                f"/api/chat/sessions/{session1_id}/messages"
            ).data
        )["messages"]
        session2_messages = json.loads(
            authenticated_client.get(
                f"/api/chat/sessions/{session2_id}/messages"
            ).data
        )["messages"]

        assert len(session1_messages) == 2
        assert len(session2_messages) == 1

        # Verify message content is isolated
        session1_contents = [m["content"] for m in session1_messages]
        session2_contents = [m["content"] for m in session2_messages]

        assert "Message for session 1" in session1_contents
        assert "Message for session 2" not in session1_contents
        assert "Message for session 2" in session2_contents

    def test_delete_and_list_flow(self, authenticated_client):
        """Test session deletion flow."""
        # Create session
        create_response = authenticated_client.post(
            "/api/chat/sessions",
            json={"initial_query": "To be deleted"},
            content_type="application/json",
        )
        session_id = json.loads(create_response.data)["session_id"]

        # Verify session exists
        get_response = authenticated_client.get(
            f"/api/chat/sessions/{session_id}"
        )
        assert get_response.status_code == 200

        # Delete session
        delete_response = authenticated_client.delete(
            f"/api/chat/sessions/{session_id}"
        )
        assert delete_response.status_code == 200
        assert json.loads(delete_response.data)["success"] is True

        # Session should be permanently deleted (hard delete)
        get_deleted_response = authenticated_client.get(
            f"/api/chat/sessions/{session_id}"
        )
        assert get_deleted_response.status_code == 404

        # Should not appear in active sessions list
        list_response = authenticated_client.get(
            "/api/chat/sessions?status=active"
        )
        list_data = json.loads(list_response.data)
        active_ids = [s["id"] for s in list_data["sessions"]]
        assert session_id not in active_ids
