# tests/api/routes/syndarix/test_projects.py
"""
Comprehensive tests for the Projects API endpoints.

Tests cover:
- CRUD operations (create, read, update, archive)
- Lifecycle operations (pause, resume)
- Authorization (ownership checks, superuser access)
- Pagination and filtering
- Error handling (not found, validation, duplicates)
"""

import uuid

import pytest
from fastapi import status


@pytest.mark.asyncio
class TestCreateProject:
    """Tests for POST /api/v1/projects endpoint."""

    async def test_create_project_success(self, client, user_token):
        """Test successful project creation."""
        response = await client.post(
            "/api/v1/projects",
            json={
                "name": "Test Project",
                "slug": "test-project",
                "description": "A test project description",
                "autonomy_level": "milestone",
            },
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_201_CREATED
        data = response.json()

        assert data["name"] == "Test Project"
        assert data["slug"] == "test-project"
        assert data["description"] == "A test project description"
        assert data["autonomy_level"] == "milestone"
        assert data["status"] == "active"
        assert data["agent_count"] == 0
        assert data["issue_count"] == 0
        assert data["active_sprint_name"] is None
        assert "id" in data
        assert "created_at" in data
        assert "updated_at" in data

    async def test_create_project_minimal_fields(self, client, user_token):
        """Test creating project with only required fields."""
        response = await client.post(
            "/api/v1/projects",
            json={
                "name": "Minimal Project",
                "slug": "minimal-project",
            },
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_201_CREATED
        data = response.json()
        assert data["name"] == "Minimal Project"
        assert data["slug"] == "minimal-project"
        assert data["autonomy_level"] == "milestone"  # Default
        assert data["status"] == "active"  # Default

    async def test_create_project_with_settings(self, client, user_token):
        """Test creating project with custom settings."""
        response = await client.post(
            "/api/v1/projects",
            json={
                "name": "Project With Settings",
                "slug": "project-with-settings",
                "settings": {"theme": "dark", "notifications": True},
            },
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_201_CREATED
        data = response.json()
        assert data["settings"]["theme"] == "dark"
        assert data["settings"]["notifications"] is True

    async def test_create_project_duplicate_slug(self, client, user_token):
        """Test that duplicate slugs are rejected."""
        # Create first project
        await client.post(
            "/api/v1/projects",
            json={"name": "First Project", "slug": "duplicate-slug"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Attempt duplicate
        response = await client.post(
            "/api/v1/projects",
            json={"name": "Second Project", "slug": "duplicate-slug"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_409_CONFLICT
        data = response.json()
        assert "already exists" in data["errors"][0]["message"].lower()

    async def test_create_project_invalid_slug_format(self, client, user_token):
        """Test that invalid slug formats are rejected."""
        # Uppercase letters
        response = await client.post(
            "/api/v1/projects",
            json={"name": "Bad Slug", "slug": "Invalid-Slug"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY

        # Starting with hyphen
        response = await client.post(
            "/api/v1/projects",
            json={"name": "Bad Slug", "slug": "-invalid"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY

        # Consecutive hyphens
        response = await client.post(
            "/api/v1/projects",
            json={"name": "Bad Slug", "slug": "invalid--slug"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY

    async def test_create_project_empty_name(self, client, user_token):
        """Test that empty name is rejected."""
        response = await client.post(
            "/api/v1/projects",
            json={"name": "", "slug": "empty-name"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY

    async def test_create_project_unauthenticated(self, client):
        """Test that unauthenticated requests are rejected."""
        response = await client.post(
            "/api/v1/projects",
            json={"name": "Test Project", "slug": "test-project"},
        )
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    async def test_create_project_all_autonomy_levels(self, client, user_token):
        """Test creating projects with all autonomy levels."""
        levels = ["full_control", "milestone", "autonomous"]

        for level in levels:
            # Slugs must use hyphens, not underscores
            slug = f"project-{level.replace('_', '-')}"
            response = await client.post(
                "/api/v1/projects",
                json={
                    "name": f"Project {level}",
                    "slug": slug,
                    "autonomy_level": level,
                },
                headers={"Authorization": f"Bearer {user_token}"},
            )
            assert response.status_code == status.HTTP_201_CREATED
            assert response.json()["autonomy_level"] == level


@pytest.mark.asyncio
class TestListProjects:
    """Tests for GET /api/v1/projects endpoint."""

    async def test_list_projects_empty(self, client, user_token):
        """Test listing projects when none exist."""
        response = await client.get(
            "/api/v1/projects",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert "data" in data
        assert "pagination" in data
        assert data["data"] == []
        assert data["pagination"]["total"] == 0

    async def test_list_projects_with_data(self, client, user_token):
        """Test listing projects returns created projects."""
        # Create projects
        for i in range(3):
            await client.post(
                "/api/v1/projects",
                json={"name": f"Project {i}", "slug": f"project-{i}"},
                headers={"Authorization": f"Bearer {user_token}"},
            )

        response = await client.get(
            "/api/v1/projects",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert len(data["data"]) == 3
        assert data["pagination"]["total"] == 3

    async def test_list_projects_pagination(self, client, user_token):
        """Test pagination works correctly."""
        # Create 5 projects
        for i in range(5):
            await client.post(
                "/api/v1/projects",
                json={"name": f"Project {i}", "slug": f"project-{i}"},
                headers={"Authorization": f"Bearer {user_token}"},
            )

        # Get first page (2 items)
        response = await client.get(
            "/api/v1/projects?page=1&limit=2",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert len(data["data"]) == 2
        assert data["pagination"]["total"] == 5
        assert data["pagination"]["page"] == 1
        assert data["pagination"]["total_pages"] == 3

        # Get second page
        response = await client.get(
            "/api/v1/projects?page=2&limit=2",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert len(data["data"]) == 2
        assert data["pagination"]["page"] == 2

    async def test_list_projects_filter_by_status(self, client, user_token):
        """Test filtering projects by status."""
        # Create active project
        await client.post(
            "/api/v1/projects",
            json={"name": "Active Project", "slug": "active-project", "status": "active"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Create paused project
        await client.post(
            "/api/v1/projects",
            json={"name": "Paused Project", "slug": "paused-project", "status": "paused"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Filter by active
        response = await client.get(
            "/api/v1/projects?status=active",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert len(data["data"]) == 1
        assert data["data"][0]["status"] == "active"

    async def test_list_projects_search(self, client, user_token):
        """Test searching projects by name."""
        await client.post(
            "/api/v1/projects",
            json={"name": "Alpha Project", "slug": "alpha-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        await client.post(
            "/api/v1/projects",
            json={"name": "Beta Project", "slug": "beta-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        response = await client.get(
            "/api/v1/projects?search=alpha",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert len(data["data"]) == 1
        assert "alpha" in data["data"][0]["name"].lower()

    async def test_list_projects_user_isolation(
        self, client, user_token, superuser_token, async_test_user
    ):
        """Test that users only see their own projects."""
        # Create project as regular user
        await client.post(
            "/api/v1/projects",
            json={"name": "User Project", "slug": "user-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Create project as superuser
        await client.post(
            "/api/v1/projects",
            json={"name": "Admin Project", "slug": "admin-project"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )

        # Regular user should only see their project
        response = await client.get(
            "/api/v1/projects",
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert len(data["data"]) == 1
        assert data["data"][0]["slug"] == "user-project"

    async def test_list_projects_superuser_all_projects(
        self, client, user_token, superuser_token
    ):
        """Test that superuser can see all projects with all_projects flag."""
        # Create project as regular user
        await client.post(
            "/api/v1/projects",
            json={"name": "User Project", "slug": "user-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Create project as superuser
        await client.post(
            "/api/v1/projects",
            json={"name": "Admin Project", "slug": "admin-project"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )

        # Superuser with all_projects=true should see both
        response = await client.get(
            "/api/v1/projects?all_projects=true",
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert len(data["data"]) == 2


@pytest.mark.asyncio
class TestGetProject:
    """Tests for GET /api/v1/projects/{project_id} endpoint."""

    async def test_get_project_success(self, client, user_token):
        """Test getting a project by ID."""
        # Create project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Get Test Project", "slug": "get-test-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Get project
        response = await client.get(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert data["id"] == project_id
        assert data["name"] == "Get Test Project"

    async def test_get_project_not_found(self, client, user_token):
        """Test getting a non-existent project."""
        fake_id = str(uuid.uuid4())
        response = await client.get(
            f"/api/v1/projects/{fake_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_404_NOT_FOUND
        assert "not found" in response.json()["errors"][0]["message"].lower()

    async def test_get_project_unauthorized(self, client, user_token, superuser_token):
        """Test that users cannot access other users' projects."""
        # Create project as superuser
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Admin Project", "slug": "admin-project"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        project_id = create_response.json()["id"]

        # Try to access as regular user
        response = await client.get(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_403_FORBIDDEN

    async def test_get_project_superuser_can_access_any(
        self, client, user_token, superuser_token
    ):
        """Test that superuser can access any project."""
        # Create project as regular user
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "User Project", "slug": "user-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Access as superuser
        response = await client.get(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {superuser_token}"},
        )

        assert response.status_code == status.HTTP_200_OK


@pytest.mark.asyncio
class TestGetProjectBySlug:
    """Tests for GET /api/v1/projects/slug/{slug} endpoint."""

    async def test_get_project_by_slug_success(self, client, user_token):
        """Test getting a project by slug."""
        # Create project
        await client.post(
            "/api/v1/projects",
            json={"name": "Slug Test Project", "slug": "slug-test-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Get by slug
        response = await client.get(
            "/api/v1/projects/slug/slug-test-project",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert data["slug"] == "slug-test-project"
        assert data["name"] == "Slug Test Project"

    async def test_get_project_by_slug_not_found(self, client, user_token):
        """Test getting a non-existent project by slug."""
        response = await client.get(
            "/api/v1/projects/slug/non-existent-slug",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_404_NOT_FOUND

    async def test_get_project_by_slug_unauthorized(
        self, client, user_token, superuser_token
    ):
        """Test that users cannot access other users' projects by slug."""
        # Create project as superuser
        await client.post(
            "/api/v1/projects",
            json={"name": "Admin Project", "slug": "admin-project"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )

        # Try to access as regular user
        response = await client.get(
            "/api/v1/projects/slug/admin-project",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_403_FORBIDDEN


@pytest.mark.asyncio
class TestUpdateProject:
    """Tests for PATCH /api/v1/projects/{project_id} endpoint."""

    async def test_update_project_success(self, client, user_token):
        """Test updating a project."""
        # Create project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Original Name", "slug": "original-slug"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Update project
        response = await client.patch(
            f"/api/v1/projects/{project_id}",
            json={"name": "Updated Name", "description": "New description"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert data["name"] == "Updated Name"
        assert data["description"] == "New description"
        assert data["slug"] == "original-slug"  # Unchanged

    async def test_update_project_slug(self, client, user_token):
        """Test updating project slug."""
        # Create project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Test Project", "slug": "old-slug"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Update slug
        response = await client.patch(
            f"/api/v1/projects/{project_id}",
            json={"slug": "new-slug"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        assert response.json()["slug"] == "new-slug"

    async def test_update_project_autonomy_level(self, client, user_token):
        """Test updating project autonomy level."""
        # Create project with milestone autonomy
        create_response = await client.post(
            "/api/v1/projects",
            json={
                "name": "Test Project",
                "slug": "test-project",
                "autonomy_level": "milestone",
            },
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Update to autonomous
        response = await client.patch(
            f"/api/v1/projects/{project_id}",
            json={"autonomy_level": "autonomous"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        assert response.json()["autonomy_level"] == "autonomous"

    async def test_update_project_not_found(self, client, user_token):
        """Test updating a non-existent project."""
        fake_id = str(uuid.uuid4())
        response = await client.patch(
            f"/api/v1/projects/{fake_id}",
            json={"name": "New Name"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_404_NOT_FOUND

    async def test_update_project_unauthorized(
        self, client, user_token, superuser_token
    ):
        """Test that users cannot update other users' projects."""
        # Create project as superuser
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Admin Project", "slug": "admin-project"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        project_id = create_response.json()["id"]

        # Try to update as regular user
        response = await client.patch(
            f"/api/v1/projects/{project_id}",
            json={"name": "Hacked Name"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_403_FORBIDDEN

    async def test_update_project_duplicate_slug(self, client, user_token):
        """Test that updating to a duplicate slug is rejected."""
        # Create two projects
        await client.post(
            "/api/v1/projects",
            json={"name": "First Project", "slug": "first-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Second Project", "slug": "second-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Try to update second project's slug to first's
        response = await client.patch(
            f"/api/v1/projects/{project_id}",
            json={"slug": "first-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_409_CONFLICT


@pytest.mark.asyncio
class TestArchiveProject:
    """Tests for DELETE /api/v1/projects/{project_id} endpoint."""

    async def test_archive_project_success(self, client, user_token):
        """Test archiving a project."""
        # Create project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Archive Test", "slug": "archive-test"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Archive project
        response = await client.delete(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        data = response.json()
        assert data["success"] is True
        assert "archived" in data["message"].lower()

        # Verify project is archived
        get_response = await client.get(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert get_response.json()["status"] == "archived"

    async def test_archive_project_already_archived(self, client, user_token):
        """Test archiving an already archived project."""
        # Create and archive project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Archive Test", "slug": "archive-test"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        await client.delete(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Try to archive again
        response = await client.delete(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        assert "already archived" in response.json()["message"].lower()

    async def test_archive_project_not_found(self, client, user_token):
        """Test archiving a non-existent project."""
        fake_id = str(uuid.uuid4())
        response = await client.delete(
            f"/api/v1/projects/{fake_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_404_NOT_FOUND

    async def test_archive_project_unauthorized(
        self, client, user_token, superuser_token
    ):
        """Test that users cannot archive other users' projects."""
        # Create project as superuser
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Admin Project", "slug": "admin-project"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        project_id = create_response.json()["id"]

        # Try to archive as regular user
        response = await client.delete(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_403_FORBIDDEN


@pytest.mark.asyncio
class TestPauseProject:
    """Tests for POST /api/v1/projects/{project_id}/pause endpoint."""

    async def test_pause_project_success(self, client, user_token):
        """Test pausing an active project."""
        # Create project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Pause Test", "slug": "pause-test"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Pause project
        response = await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        assert response.json()["status"] == "paused"

    async def test_pause_already_paused_project(self, client, user_token):
        """Test that pausing an already paused project returns validation error."""
        # Create and pause project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Pause Test", "slug": "pause-test"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Try to pause again
        response = await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
        assert "already paused" in response.json()["errors"][0]["message"].lower()

    async def test_pause_archived_project(self, client, user_token):
        """Test that pausing an archived project returns validation error."""
        # Create and archive project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Archive Test", "slug": "archive-test"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        await client.delete(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Try to pause
        response = await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
        assert "archived" in response.json()["errors"][0]["message"].lower()

    async def test_pause_completed_project(self, client, user_token):
        """Test that pausing a completed project returns validation error."""
        # Create project with completed status
        create_response = await client.post(
            "/api/v1/projects",
            json={
                "name": "Completed Test",
                "slug": "completed-test",
                "status": "completed",
            },
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Try to pause
        response = await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
        assert "completed" in response.json()["errors"][0]["message"].lower()

    async def test_pause_project_not_found(self, client, user_token):
        """Test pausing a non-existent project."""
        fake_id = str(uuid.uuid4())
        response = await client.post(
            f"/api/v1/projects/{fake_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_404_NOT_FOUND

    async def test_pause_project_unauthorized(
        self, client, user_token, superuser_token
    ):
        """Test that users cannot pause other users' projects."""
        # Create project as superuser
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Admin Project", "slug": "admin-project"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        project_id = create_response.json()["id"]

        # Try to pause as regular user
        response = await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_403_FORBIDDEN


@pytest.mark.asyncio
class TestResumeProject:
    """Tests for POST /api/v1/projects/{project_id}/resume endpoint."""

    async def test_resume_project_success(self, client, user_token):
        """Test resuming a paused project."""
        # Create and pause project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Resume Test", "slug": "resume-test"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Resume project
        response = await client.post(
            f"/api/v1/projects/{project_id}/resume",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_200_OK
        assert response.json()["status"] == "active"

    async def test_resume_already_active_project(self, client, user_token):
        """Test that resuming an active project returns validation error."""
        # Create project (active by default)
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Active Test", "slug": "active-test"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Try to resume
        response = await client.post(
            f"/api/v1/projects/{project_id}/resume",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
        assert "already active" in response.json()["errors"][0]["message"].lower()

    async def test_resume_archived_project(self, client, user_token):
        """Test that resuming an archived project returns validation error."""
        # Create and archive project
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Archive Test", "slug": "archive-test"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        await client.delete(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        # Try to resume
        response = await client.post(
            f"/api/v1/projects/{project_id}/resume",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
        assert "archived" in response.json()["errors"][0]["message"].lower()

    async def test_resume_completed_project(self, client, user_token):
        """Test that resuming a completed project returns validation error."""
        # Create project with completed status
        create_response = await client.post(
            "/api/v1/projects",
            json={
                "name": "Completed Test",
                "slug": "completed-test",
                "status": "completed",
            },
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Try to resume
        response = await client.post(
            f"/api/v1/projects/{project_id}/resume",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
        assert "completed" in response.json()["errors"][0]["message"].lower()

    async def test_resume_project_not_found(self, client, user_token):
        """Test resuming a non-existent project."""
        fake_id = str(uuid.uuid4())
        response = await client.post(
            f"/api/v1/projects/{fake_id}/resume",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_404_NOT_FOUND

    async def test_resume_project_unauthorized(
        self, client, user_token, superuser_token
    ):
        """Test that users cannot resume other users' projects."""
        # Create and pause project as superuser
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "Admin Project", "slug": "admin-project"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        project_id = create_response.json()["id"]

        await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {superuser_token}"},
        )

        # Try to resume as regular user
        response = await client.post(
            f"/api/v1/projects/{project_id}/resume",
            headers={"Authorization": f"Bearer {user_token}"},
        )

        assert response.status_code == status.HTTP_403_FORBIDDEN


@pytest.mark.asyncio
class TestProjectWorkflow:
    """Integration tests for project lifecycle workflows."""

    async def test_full_project_lifecycle(self, client, user_token):
        """Test complete project lifecycle: create -> pause -> resume -> archive."""
        # Create
        create_response = await client.post(
            "/api/v1/projects",
            json={
                "name": "Lifecycle Test",
                "slug": "lifecycle-test",
                "description": "Testing full lifecycle",
            },
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert create_response.status_code == status.HTTP_201_CREATED
        project_id = create_response.json()["id"]

        # Pause
        pause_response = await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert pause_response.status_code == status.HTTP_200_OK
        assert pause_response.json()["status"] == "paused"

        # Resume
        resume_response = await client.post(
            f"/api/v1/projects/{project_id}/resume",
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert resume_response.status_code == status.HTTP_200_OK
        assert resume_response.json()["status"] == "active"

        # Archive
        archive_response = await client.delete(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert archive_response.status_code == status.HTTP_200_OK

        # Verify final state
        get_response = await client.get(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {user_token}"},
        )
        assert get_response.json()["status"] == "archived"

    async def test_superuser_can_manage_any_project(
        self, client, user_token, superuser_token
    ):
        """Test that superuser can perform all operations on any project."""
        # Create project as regular user
        create_response = await client.post(
            "/api/v1/projects",
            json={"name": "User Project", "slug": "user-project"},
            headers={"Authorization": f"Bearer {user_token}"},
        )
        project_id = create_response.json()["id"]

        # Superuser can read
        get_response = await client.get(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        assert get_response.status_code == status.HTTP_200_OK

        # Superuser can update
        update_response = await client.patch(
            f"/api/v1/projects/{project_id}",
            json={"description": "Updated by admin"},
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        assert update_response.status_code == status.HTTP_200_OK

        # Superuser can pause
        pause_response = await client.post(
            f"/api/v1/projects/{project_id}/pause",
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        assert pause_response.status_code == status.HTTP_200_OK

        # Superuser can resume
        resume_response = await client.post(
            f"/api/v1/projects/{project_id}/resume",
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        assert resume_response.status_code == status.HTTP_200_OK

        # Superuser can archive
        archive_response = await client.delete(
            f"/api/v1/projects/{project_id}",
            headers={"Authorization": f"Bearer {superuser_token}"},
        )
        assert archive_response.status_code == status.HTTP_200_OK
