"""Tests for workflow graph schema and router behavior."""


class TestWorkflowAPI:
    """Workflow CRUD and graph validation test cases."""

    def _minimal_nodes(self):
        return [
            {
                "id": "start_1",
                "name": "start_1",
                "type": "start",
                "isStart": True,
                "metadata": {"position": {"x": 80, "y": 80}},
            },
            {
                "id": "assistant_1",
                "name": "assistant_1",
                "type": "assistant",
                "metadata": {"position": {"x": 280, "y": 80}},
                "prompt": "You are the first assistant node.",
            },
        ]

    def test_create_workflow_with_canonical_graph(self, client):
        payload = {
            "name": "Canonical Graph",
            "nodes": self._minimal_nodes(),
            "edges": [
                {
                    "id": "edge_start_assistant",
                    "fromNodeId": "start_1",
                    "toNodeId": "assistant_1",
                    "condition": {"type": "always"},
                }
            ],
        }

        resp = client.post("/api/workflows", json=payload)
        assert resp.status_code == 200
        data = resp.json()
        assert data["name"] == "Canonical Graph"
        assert data["nodeCount"] == 2
        assert data["nodes"][0]["id"] == "start_1"
        assert data["edges"][0]["fromNodeId"] == "start_1"
        assert data["edges"][0]["toNodeId"] == "assistant_1"

    def test_create_workflow_with_legacy_graph(self, client):
        payload = {
            "name": "Legacy Graph",
            "nodes": [
                {
                    "name": "legacy_start",
                    "type": "conversation",
                    "isStart": True,
                    "metadata": {"position": {"x": 100, "y": 100}},
                },
                {
                    "name": "legacy_human",
                    "type": "human",
                    "metadata": {"position": {"x": 300, "y": 100}},
                },
            ],
            "edges": [
                {
                    "from": "legacy_start",
                    "to": "legacy_human",
                    "label": "人工",
                }
            ],
        }

        resp = client.post("/api/workflows", json=payload)
        assert resp.status_code == 200
        data = resp.json()
        assert data["nodes"][0]["type"] == "assistant"
        assert data["nodes"][1]["type"] == "human_transfer"
        assert data["edges"][0]["fromNodeId"] == "legacy_start"
        assert data["edges"][0]["toNodeId"] == "legacy_human"
        assert data["edges"][0]["condition"]["type"] == "contains"

    def test_create_workflow_without_start_node_fails(self, client):
        payload = {
            "name": "No Start",
            "nodes": [
                {"id": "node_1", "name": "node_1", "type": "assistant", "metadata": {"position": {"x": 0, "y": 0}}},
            ],
            "edges": [],
        }
        resp = client.post("/api/workflows", json=payload)
        assert resp.status_code == 422

    def test_create_workflow_with_invalid_edge_fails(self, client):
        payload = {
            "name": "Bad Edge",
            "nodes": self._minimal_nodes(),
            "edges": [
                {"id": "edge_bad", "fromNodeId": "missing", "toNodeId": "assistant_1", "condition": {"type": "always"}},
            ],
        }
        resp = client.post("/api/workflows", json=payload)
        assert resp.status_code == 422

    def test_update_workflow_nodes_and_edges(self, client):
        create_payload = {
            "name": "Before Update",
            "nodes": self._minimal_nodes(),
            "edges": [
                {
                    "id": "edge_start_assistant",
                    "fromNodeId": "start_1",
                    "toNodeId": "assistant_1",
                    "condition": {"type": "always"},
                }
            ],
        }
        create_resp = client.post("/api/workflows", json=create_payload)
        assert create_resp.status_code == 200
        workflow_id = create_resp.json()["id"]

        update_payload = {
            "name": "After Update",
            "nodes": [
                {
                    "id": "start_1",
                    "name": "start_1",
                    "type": "start",
                    "isStart": True,
                    "metadata": {"position": {"x": 50, "y": 50}},
                },
                {
                    "id": "assistant_2",
                    "name": "assistant_2",
                    "type": "assistant",
                    "metadata": {"position": {"x": 250, "y": 50}},
                    "prompt": "new prompt",
                },
                {
                    "id": "end_1",
                    "name": "end_1",
                    "type": "end",
                    "metadata": {"position": {"x": 450, "y": 50}},
                },
            ],
            "edges": [
                {
                    "id": "edge_start_assistant2",
                    "fromNodeId": "start_1",
                    "toNodeId": "assistant_2",
                    "condition": {"type": "always"},
                },
                {
                    "id": "edge_assistant2_end",
                    "fromNodeId": "assistant_2",
                    "toNodeId": "end_1",
                    "condition": {"type": "contains", "source": "user", "value": "结束"},
                },
            ],
        }

        update_resp = client.put(f"/api/workflows/{workflow_id}", json=update_payload)
        assert update_resp.status_code == 200
        updated = update_resp.json()
        assert updated["name"] == "After Update"
        assert updated["nodeCount"] == 3
        assert len(updated["nodes"]) == 3
        assert len(updated["edges"]) == 2
