"""Bulk Import Service integration tests."""

import pytest
import uuid

from gqldb.client import GqldbClient
from gqldb.types import GraphType, NodeData, EdgeData
from tests.conftest import drop_test_graph


@pytest.mark.integration
class TestBulkImport:
    """Tests for bulk import service."""

    @pytest.fixture
    def test_graph(self, connected_client: GqldbClient, request):
        """Create a temporary test graph."""
        graph_name = f"test_{request.node.name}_{uuid.uuid4().hex[:8]}"
        connected_client.create_graph(graph_name, GraphType.OPEN, "Test bulk import graph")
        yield graph_name
        drop_test_graph(connected_client, graph_name)

    def test_start_bulk_import(self, connected_client: GqldbClient, test_graph: str):
        """Test starting a bulk import session."""
        session = connected_client.start_bulk_import(test_graph, checkpoint_every=1000)
        assert session.success
        assert session.session_id != ""
        print(f"Started bulk import session: {session.session_id}")

        # Clean up - abort the session
        connected_client.abort_bulk_import(session.session_id)

    def test_bulk_import_workflow(self, connected_client: GqldbClient, test_graph: str):
        """Test the complete bulk import workflow."""
        # Step 1: Start bulk import session
        session = connected_client.start_bulk_import(test_graph, checkpoint_every=0)
        assert session.success
        print(f"Started bulk import session: {session.session_id}")

        # Step 2: Insert nodes with bulk import session
        nodes = [
            NodeData(labels=["BulkPerson"], properties={"name": "Alice", "idx": 1}),
            NodeData(labels=["BulkPerson"], properties={"name": "Bob", "idx": 2}),
            NodeData(labels=["BulkPerson"], properties={"name": "Charlie", "idx": 3}),
        ]

        node_result = connected_client.insert_nodes(
            test_graph,
            nodes,
            bulk_import_session_id=session.session_id
        )
        assert node_result.success
        assert node_result.node_count == 3
        print(f"Inserted {node_result.node_count} nodes")

        # Step 3: Get status
        status = connected_client.get_bulk_import_status(session.session_id)
        print(f"Bulk import status: active={status.is_active}, graph={status.graph_name}, records={status.record_count}")

        # Step 4: End bulk import
        end_result = connected_client.end_bulk_import(session.session_id)
        assert end_result.success
        print(f"Ended bulk import: {end_result.total_records} total records")

    def test_abort_bulk_import(self, connected_client: GqldbClient, test_graph: str):
        """Test aborting a bulk import session."""
        # Start bulk import session
        session = connected_client.start_bulk_import(test_graph, checkpoint_every=0)
        assert session.success
        print(f"Started bulk import session: {session.session_id}")

        # Insert some data
        nodes = [
            NodeData(labels=["AbortTest"], properties={"name": "TestNode"}),
        ]
        connected_client.insert_nodes(
            test_graph,
            nodes,
            bulk_import_session_id=session.session_id
        )

        # Abort the session
        abort_result = connected_client.abort_bulk_import(session.session_id)
        assert abort_result.success
        print("Aborted bulk import session successfully")

    def test_insert_edges_with_bulk_session(self, connected_client: GqldbClient, test_graph: str):
        """Test inserting edges with bulk import session."""
        # Start bulk import session
        session = connected_client.start_bulk_import(test_graph, checkpoint_every=0)
        assert session.success

        # Insert nodes
        nodes = [
            NodeData(labels=["Person"], properties={"name": "Alice"}),
            NodeData(labels=["Person"], properties={"name": "Bob"}),
        ]
        node_result = connected_client.insert_nodes(
            test_graph,
            nodes,
            bulk_import_session_id=session.session_id
        )
        assert node_result.success

        # Query to get node IDs (bulk import doesn't return IDs immediately)
        from gqldb.client import QueryConfig
        resp = connected_client.gql(
            "MATCH (n:Person) RETURN id(n) AS node_id ORDER BY n.name",
            QueryConfig(graph_name=test_graph)
        )

        node_ids = []
        for i in range(resp.row_count):
            row = resp.rows[i]
            value = resp.get_by_name(row, "node_id")
            if value:
                node_ids.append(value)

        if len(node_ids) >= 2:
            # Insert edges with bulk session
            edges = [
                EdgeData(
                    label="KNOWS",
                    from_node_id=node_ids[0],
                    to_node_id=node_ids[1],
                    properties={"since": 2024}
                ),
            ]
            edge_result = connected_client.insert_edges(
                test_graph,
                edges,
                bulk_import_session_id=session.session_id
            )
            assert edge_result.success
            print(f"Inserted {edge_result.edge_count} edges with bulk session")

        # End the session
        connected_client.end_bulk_import(session.session_id)
