from unittest.mock import AsyncMock, MagicMock

import pytest

from retab.resources.workflows.runs.steps.client import AsyncWorkflowSteps, WorkflowSteps


def test_workflow_steps_list_uses_full_steps_route() -> None:
    client = MagicMock()
    client._prepared_request.return_value = [
        {
            "run_id": "run_123",
            "organization_id": "org_123",
            "node_id": "extract-1",
            "step_id": "extract-1",
            "node_type": "extract",
            "node_label": "Extract",
            "status": "completed",
        }
    ]

    steps = WorkflowSteps(client=client).list("run_123")

    request = client._prepared_request.call_args.args[0]
    assert request.method == "GET"
    assert request.url == "/workflows/runs/run_123/steps"
    assert len(steps) == 1
    assert steps[0].node_id == "extract-1"
    assert "output" not in steps[0].model_dump()


@pytest.mark.asyncio
async def test_async_workflow_steps_list_uses_full_steps_route() -> None:
    client = MagicMock()
    client._prepared_request = AsyncMock(return_value=[
        {
            "run_id": "run_123",
            "organization_id": "org_123",
            "node_id": "extract-1",
            "step_id": "extract-1",
            "node_type": "extract",
            "node_label": "Extract",
            "status": "completed",
        }
    ])

    steps = await AsyncWorkflowSteps(client=client).list("run_123")

    request = client._prepared_request.call_args.args[0]
    assert request.method == "GET"
    assert request.url == "/workflows/runs/run_123/steps"
    assert len(steps) == 1
    assert steps[0].node_id == "extract-1"
    assert "output" not in steps[0].model_dump()


def test_workflow_steps_get_omits_raw_output() -> None:
    client = MagicMock()
    client._prepared_request.return_value = {
        "node_id": "extract-1",
        "node_type": "extract",
        "node_label": "Extract",
        "status": "completed",
        "handle_outputs": {
            "output-json-0": {
                "type": "json",
                "data": {"invoice_number": "INV-001"},
            },
        },
        "handle_inputs": None,
    }

    step = WorkflowSteps(client=client).get("run_123", "extract-1")

    request = client._prepared_request.call_args.args[0]
    assert request.method == "GET"
    assert request.url == "/workflows/runs/run_123/steps/extract-1"
    assert "output" not in step.model_dump()
    assert step.handle_outputs is not None
    assert step.handle_outputs["output-json-0"]["data"] == {"invoice_number": "INV-001"}


@pytest.mark.asyncio
async def test_async_workflow_steps_get_omits_raw_output() -> None:
    client = MagicMock()
    client._prepared_request = AsyncMock(return_value={
        "node_id": "start-json-1",
        "node_type": "start_json",
        "node_label": "Start JSON",
        "status": "completed",
        "handle_outputs": {
            "output-json-0": {
                "type": "json",
                "data": {"payload": {"ok": True}},
            },
        },
        "handle_inputs": {},
    })

    step = await AsyncWorkflowSteps(client=client).get("run_123", "start-json-1")

    assert "output" not in step.model_dump()
    assert step.handle_outputs is not None
    assert step.handle_outputs["output-json-0"]["data"] == {"payload": {"ok": True}}
