"""Tests for Users client."""

import pytest
from pytest_httpx import HTTPXMock

from concentriq import ConcentriqClient
from concentriq.auth import ApiKeyAuth


class TestUsersList:
    """Tests for Users.list() behavior."""

    def test_list_returns_list_of_users(self, httpx_mock: HTTPXMock):
        """List should return a list of user data."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/users",
            json={
                "meta": {"status": 200},
                "data": {
                    "users": [
                        {"id": 1, "name": "Alice Smith", "email": "alice@test.com"},
                        {"id": 2, "name": "Bob Jones", "email": "bob@test.com"},
                    ]
                },
            },
        )

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

        assert isinstance(result, list)
        assert len(result) == 2
        assert result[0]["id"] == 1
        assert result[1]["name"] == "Bob Jones"

    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/users",
            json={"meta": {"status": 200}, "data": {"users": []}},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.users.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/users",
            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.users.list()


class TestUsersCreate:
    """Tests for Users.create() behavior."""

    def test_create_returns_created_user(self, httpx_mock: HTTPXMock):
        """Create should return the newly created user data."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/users",
            method="POST",
            json={
                "meta": {"status": 201},
                "data": {
                    "userId": 456,
                    "password": "temp123",
                },
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.users.create(
            {
                "name": "New User",
                "email": "newuser@test.com",
                "organizationId": 1,
            }
        )

        assert result["userId"] == 456
        assert "password" in result

    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/users",
            method="POST",
            status_code=400,
            json={"error": "email 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.users.create({})

    def test_create_raises_authentication_error_when_unauthorized(
        self, httpx_mock: HTTPXMock
    ):
        """Create should raise AuthenticationError when not authenticated."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/users",
            method="POST",
            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.users.create({"name": "Test"})


class TestUsersUpdate:
    """Tests for Users.update() behavior."""

    def test_update_returns_success(self, httpx_mock: HTTPXMock):
        """Update should complete successfully."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/users/123",
            method="PATCH",
            json={
                "meta": {"status": 200},
                "data": {"success": "User successfully modified."},
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v1.users.update(123, {"name": "Updated Name"})

        assert result is None

    def test_update_raises_not_found_for_invalid_id(self, httpx_mock: HTTPXMock):
        """Update should raise NotFoundError for non-existent user."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/users/99999",
            method="PATCH",
            status_code=404,
            json={"error": "User 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.users.update(99999, {"name": "Updated"})

    def test_update_raises_validation_error_on_invalid_data(
        self, httpx_mock: HTTPXMock
    ):
        """Update should raise ValidationError when data is invalid."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/users/123",
            method="PATCH",
            status_code=400,
            json={"error": "Invalid data"},
        )

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

        from concentriq.exceptions import ValidationError

        with pytest.raises(ValidationError):
            client.v1.users.update(123, {"invalid": "data"})

    def test_update_raises_authentication_error_when_unauthorized(
        self, httpx_mock: HTTPXMock
    ):
        """Update should raise AuthenticationError when not authenticated."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/users/123",
            method="PATCH",
            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.users.update(123, {"name": "Updated"})
