"""Tests for Workflows client."""

import pytest
from pytest_httpx import HTTPXMock

from concentriq import ConcentriqClient
from concentriq.auth import ApiKeyAuth


class TestWorkflowsList:
    """Tests for Workflows.list() behavior."""

    def test_list_returns_list_of_workflows_with_nested_stages_and_actions(
        self, httpx_mock: HTTPXMock
    ):
        """List should return workflows with nested stages and actions."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows",
            json={
                "meta": {"status": 200},
                "data": {
                    "workflows": [
                        {
                            "id": 1,
                            "name": "Clinical Workflow",
                            "stages": [
                                {
                                    "id": 10,
                                    "name": "Submitted",
                                    "status": "pending",
                                    "orderInWorkflow": 1,
                                    "actions": [
                                        {
                                            "id": 100,
                                            "name": "Approve",
                                            "stageId": 10,
                                            "targetStageId": 11,
                                            "associatedFunctions": ["sendEmail"],
                                            "color": "#00FF00",
                                            "icon": "check",
                                        }
                                    ],
                                },
                                {
                                    "id": 11,
                                    "name": "Approved",
                                    "status": "complete",
                                    "orderInWorkflow": 2,
                                    "actions": [],
                                },
                            ],
                        },
                        {
                            "id": 2,
                            "name": "Research Workflow",
                            "stages": [
                                {
                                    "id": 20,
                                    "name": "In Progress",
                                    "status": "active",
                                    "orderInWorkflow": 1,
                                    "actions": [],
                                }
                            ],
                        },
                    ]
                },
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.workflows.list()

        assert isinstance(result, list)
        assert len(result) == 2
        assert result[0]["id"] == 1
        assert result[0]["name"] == "Clinical Workflow"
        assert len(result[0]["stages"]) == 2
        assert result[0]["stages"][0]["name"] == "Submitted"
        assert len(result[0]["stages"][0]["actions"]) == 1
        assert result[0]["stages"][0]["actions"][0]["name"] == "Approve"

    def test_list_with_organization_id_filter(self, httpx_mock: HTTPXMock):
        """List should support organizationId query parameter."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows?organizationId=5",
            json={
                "meta": {"status": 200},
                "data": {
                    "workflows": [
                        {
                            "id": 1,
                            "name": "Org 5 Workflow",
                            "stages": [],
                        }
                    ]
                },
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.workflows.list(organization_id=5)

        assert isinstance(result, list)
        assert len(result) == 1
        assert result[0]["name"] == "Org 5 Workflow"

    def test_list_with_group_id_filter(self, httpx_mock: HTTPXMock):
        """List should support groupId query parameter."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows?groupId=10",
            json={
                "meta": {"status": 200},
                "data": {
                    "workflows": [
                        {
                            "id": 1,
                            "name": "Group 10 Workflow",
                            "stages": [],
                        }
                    ]
                },
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.workflows.list(group_id=10)

        assert isinstance(result, list)
        assert len(result) == 1

    def test_list_returns_empty_list_when_no_results(self, httpx_mock: HTTPXMock):
        """List should return empty list when API returns no data."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows",
            json={"meta": {"status": 200}, "data": {"workflows": []}},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.workflows.list()

        assert result == []

    def test_list_raises_authentication_error_when_unauthorized(
        self, httpx_mock: HTTPXMock
    ):
        """List should raise AuthenticationError when API returns 401."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows",
            status_code=401,
            json={"error": "Unauthorized"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )

        from concentriq.exceptions import AuthenticationError

        with pytest.raises(AuthenticationError):
            client.v1.workflows.list()


class TestWorkflowsCreate:
    """Tests for Workflows.create() behavior."""

    def test_create_returns_created_workflow(self, httpx_mock: HTTPXMock):
        """Create should return the newly created workflow data."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows",
            method="POST",
            json={
                "meta": {"status": 201},
                "data": {
                    "id": 456,
                    "name": "New Workflow",
                },
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.workflows.create({"name": "New Workflow", "groups": [1, 2]})

        assert result["id"] == 456
        assert result["name"] == "New Workflow"

    def test_create_raises_validation_error_on_invalid_data(
        self, httpx_mock: HTTPXMock
    ):
        """Create should raise ValidationError when data is invalid."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows",
            method="POST",
            status_code=400,
            json={"error": "name is required"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )

        from concentriq.exceptions import ValidationError

        with pytest.raises(ValidationError):
            client.v1.workflows.create({})

    def test_create_raises_authorization_error_when_not_admin(
        self, httpx_mock: HTTPXMock
    ):
        """Create should raise AuthorizationError when user is not admin."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows",
            method="POST",
            status_code=403,
            json={"error": "Admin access required"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )

        from concentriq.exceptions import AuthorizationError

        with pytest.raises(AuthorizationError):
            client.v1.workflows.create({"name": "Test"})


class TestWorkflowsUpdate:
    """Tests for Workflows.update() behavior."""

    def test_update_returns_updated_workflow(self, httpx_mock: HTTPXMock):
        """Update should return the updated workflow data."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows/123",
            method="PATCH",
            json={
                "meta": {"status": 200},
                "data": {
                    "id": 123,
                    "name": "Updated Workflow",
                    "groups": [1, 2, 3],
                },
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.workflows.update(
            123, {"name": "Updated Workflow", "groups": [1, 2, 3]}
        )

        assert result["id"] == 123
        assert result["name"] == "Updated Workflow"
        assert result["groups"] == [1, 2, 3]

    def test_update_raises_not_found_for_invalid_id(self, httpx_mock: HTTPXMock):
        """Update should raise NotFoundError for non-existent workflow."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows/99999",
            method="PATCH",
            status_code=404,
            json={"error": "Workflow not found"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )

        from concentriq.exceptions import NotFoundError

        with pytest.raises(NotFoundError):
            client.v1.workflows.update(99999, {"name": "Updated"})

    def test_update_raises_authorization_error_when_not_admin(
        self, httpx_mock: HTTPXMock
    ):
        """Update should raise AuthorizationError when user is not admin."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows/123",
            method="PATCH",
            status_code=403,
            json={"error": "Admin access required"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )

        from concentriq.exceptions import AuthorizationError

        with pytest.raises(AuthorizationError):
            client.v1.workflows.update(123, {"name": "Updated"})


class TestWorkflowsDelete:
    """Tests for Workflows.delete() behavior."""

    def test_delete_returns_success(self, httpx_mock: HTTPXMock):
        """Delete should complete successfully."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows/123",
            method="DELETE",
            json={
                "meta": {"status": 200},
                "data": {"success": "Workflow: 123 successfully deleted."},
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.workflows.delete(123)

        assert result is None

    def test_delete_raises_not_found_for_invalid_id(self, httpx_mock: HTTPXMock):
        """Delete should raise NotFoundError for non-existent workflow."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows/99999",
            method="DELETE",
            status_code=404,
            json={"error": "Workflow not found"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )

        from concentriq.exceptions import NotFoundError

        with pytest.raises(NotFoundError):
            client.v1.workflows.delete(99999)

    def test_delete_raises_authorization_error_when_not_admin(
        self, httpx_mock: HTTPXMock
    ):
        """Delete should raise AuthorizationError when user is not admin."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/workflows/123",
            method="DELETE",
            status_code=403,
            json={"error": "Admin access required"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )

        from concentriq.exceptions import AuthorizationError

        with pytest.raises(AuthorizationError):
            client.v1.workflows.delete(123)
