"""Integration tests for admin feature flag endpoints."""

import pytest
from httpx import AsyncClient


class TestAdminFeatureFlags:

    @pytest.mark.asyncio
    async def test_create_feature_flag(
        self, client: AsyncClient, admin_auth_headers: dict
    ):
        """Create a feature flag."""
        response = await client.post(
            "/api/v1/admin/feature-flags",
            json={
                "flag_key": "test_feature",
                "display_name": "Test Feature",
                "description": "A test feature flag",
            },
            headers=admin_auth_headers,
        )
        assert response.status_code == 201
        data = response.json()
        assert data["flag_key"] == "test_feature"
        assert data["display_name"] == "Test Feature"

    @pytest.mark.asyncio
    async def test_list_feature_flags(
        self, client: AsyncClient, admin_auth_headers: dict
    ):
        """List feature flags."""
        # Create a flag first
        await client.post(
            "/api/v1/admin/feature-flags",
            json={"flag_key": "list_test", "display_name": "List Test"},
            headers=admin_auth_headers,
        )

        response = await client.get("/api/v1/admin/feature-flags", headers=admin_auth_headers)
        assert response.status_code == 200
        flags = response.json()
        assert len(flags) >= 1

    @pytest.mark.asyncio
    async def test_update_feature_flag(
        self, client: AsyncClient, admin_auth_headers: dict
    ):
        """Update a feature flag."""
        create_resp = await client.post(
            "/api/v1/admin/feature-flags",
            json={"flag_key": "update_test", "display_name": "Before"},
            headers=admin_auth_headers,
        )
        flag_id = create_resp.json()["id"]

        response = await client.put(
            f"/api/v1/admin/feature-flags/{flag_id}",
            json={"display_name": "After"},
            headers=admin_auth_headers,
        )
        assert response.status_code == 200
        assert response.json()["display_name"] == "After"

    @pytest.mark.asyncio
    async def test_update_plan_default(
        self, client: AsyncClient, admin_auth_headers: dict
    ):
        """Update a plan feature default."""
        create_resp = await client.post(
            "/api/v1/admin/feature-flags",
            json={"flag_key": "plan_default_test", "display_name": "Plan Default Test"},
            headers=admin_auth_headers,
        )
        flag_id = create_resp.json()["id"]

        response = await client.put(
            "/api/v1/admin/feature-flags/plan-defaults",
            json={"plan": "free", "flag_id": flag_id, "enabled": True},
            headers=admin_auth_headers,
        )
        assert response.status_code == 200

        # Verify in list
        list_resp = await client.get("/api/v1/admin/feature-flags", headers=admin_auth_headers)
        flag = next(f for f in list_resp.json() if f["id"] == flag_id)
        assert any(d["plan"] == "free" and d["enabled"] for d in flag["plan_defaults"])

    @pytest.mark.asyncio
    async def test_delete_feature_flag_cascades(
        self, client: AsyncClient, admin_auth_headers: dict
    ):
        """Delete a feature flag cascades to plan defaults."""
        create_resp = await client.post(
            "/api/v1/admin/feature-flags",
            json={"flag_key": "delete_test", "display_name": "Delete Test"},
            headers=admin_auth_headers,
        )
        flag_id = create_resp.json()["id"]

        # Add a plan default
        await client.put(
            "/api/v1/admin/feature-flags/plan-defaults",
            json={"plan": "pro", "flag_id": flag_id, "enabled": True},
            headers=admin_auth_headers,
        )

        # Delete the flag
        response = await client.delete(
            f"/api/v1/admin/feature-flags/{flag_id}",
            headers=admin_auth_headers,
        )
        assert response.status_code == 204

        # Verify gone
        list_resp = await client.get("/api/v1/admin/feature-flags", headers=admin_auth_headers)
        assert not any(f["id"] == flag_id for f in list_resp.json())

    @pytest.mark.asyncio
    async def test_duplicate_flag_key_fails(
        self, client: AsyncClient, admin_auth_headers: dict
    ):
        """Duplicate flag_key returns 409."""
        await client.post(
            "/api/v1/admin/feature-flags",
            json={"flag_key": "dupe_test", "display_name": "First"},
            headers=admin_auth_headers,
        )
        response = await client.post(
            "/api/v1/admin/feature-flags",
            json={"flag_key": "dupe_test", "display_name": "Second"},
            headers=admin_auth_headers,
        )
        assert response.status_code == 409

    @pytest.mark.asyncio
    async def test_non_admin_cannot_access(
        self, client: AsyncClient, auth_headers: dict
    ):
        """Non-admin gets 403."""
        response = await client.get("/api/v1/admin/feature-flags", headers=auth_headers)
        assert response.status_code == 403
