"""Tests for the public survey submission endpoint."""
import pytest


@pytest.mark.asyncio
async def test_submit_survey_success(client):
    """POST valid survey data returns 200 with id."""
    payload = {
        "respondent_name": "Test Engineer",
        "responses": {
            "prereqs": ["Who's affected", "What changed recently"],
            "verify_fix": "Have the user confirm it's working",
            "steps_at_a_time": "5 steps",
        },
    }
    response = await client.post("/api/v1/survey/submit", json=payload)
    assert response.status_code == 200
    data = response.json()
    assert "id" in data
    assert data["message"] == "Thank you for your response!"


@pytest.mark.asyncio
async def test_submit_survey_anonymous(client):
    """Survey works without respondent_name."""
    payload = {
        "responses": {
            "first_step": "Check if it's one user or many",
        },
    }
    response = await client.post("/api/v1/survey/submit", json=payload)
    assert response.status_code == 200
    assert "id" in response.json()


@pytest.mark.asyncio
async def test_submit_survey_missing_responses(client):
    """Missing responses field returns 422."""
    payload = {"respondent_name": "Test"}
    response = await client.post("/api/v1/survey/submit", json=payload)
    assert response.status_code == 422


@pytest.mark.asyncio
async def test_submit_survey_empty_body(client):
    """Empty body returns 422."""
    response = await client.post("/api/v1/survey/submit", json={})
    assert response.status_code == 422


@pytest.mark.asyncio
async def test_check_invite_status_not_found(client):
    """Invalid token returns 404."""
    response = await client.get("/api/v1/survey/invite/nonexistent")
    assert response.status_code == 404


@pytest.mark.asyncio
async def test_submit_with_completed_token_returns_409(client, admin_auth_headers):
    """Submitting with an already-used token returns 409."""
    # Create invite
    create_res = await client.post(
        "/api/v1/admin/survey-invites",
        json={"recipient_name": "Test User"},
        headers=admin_auth_headers,
    )
    assert create_res.status_code == 200
    token = create_res.json()["token"]

    # First submit succeeds
    submit_res = await client.post(
        "/api/v1/survey/submit",
        json={"responses": {"q1": "answer"}, "token": token},
    )
    assert submit_res.status_code == 200

    # Second submit with same token returns 409
    submit_res2 = await client.post(
        "/api/v1/survey/submit",
        json={"responses": {"q1": "answer"}, "token": token},
    )
    assert submit_res2.status_code == 409


@pytest.mark.asyncio
async def test_create_invite_requires_admin(client, auth_headers):
    """Non-admin users cannot create invites."""
    response = await client.post(
        "/api/v1/admin/survey-invites",
        json={"recipient_name": "Test"},
        headers=auth_headers,
    )
    assert response.status_code == 403


@pytest.mark.asyncio
async def test_create_and_list_invites(client, admin_auth_headers):
    """Admin can create and list invites."""
    # Create
    create_res = await client.post(
        "/api/v1/admin/survey-invites",
        json={"recipient_name": "John Smith", "recipient_email": "john@msp.example.com"},
        headers=admin_auth_headers,
    )
    assert create_res.status_code == 200
    data = create_res.json()
    assert data["recipient_name"] == "John Smith"
    assert data["status"] == "pending"
    assert "survey_url" in data

    # List
    list_res = await client.get("/api/v1/admin/survey-invites", headers=admin_auth_headers)
    assert list_res.status_code == 200
    invites = list_res.json()
    assert len(invites) >= 1


@pytest.mark.asyncio
async def test_list_survey_responses_admin(client, admin_auth_headers):
    """Admin can list survey responses."""
    await client.post(
        "/api/v1/survey/submit",
        json={"respondent_name": "Tester", "responses": {"q1": "answer"}},
    )
    res = await client.get("/api/v1/admin/survey-responses", headers=admin_auth_headers)
    assert res.status_code == 200
    data = res.json()
    assert "responses" in data
    assert "total" in data
    assert "this_week" in data
    assert data["total"] >= 1
    assert data["responses"][0]["respondent_name"] == "Tester"
    assert data["responses"][0]["source"] == "direct"


@pytest.mark.asyncio
async def test_list_survey_responses_requires_admin(client, auth_headers):
    """Non-admin cannot list survey responses."""
    res = await client.get("/api/v1/admin/survey-responses", headers=auth_headers)
    assert res.status_code == 403


@pytest.mark.asyncio
async def test_export_survey_responses_csv(client, admin_auth_headers):
    """Admin can export survey responses as CSV."""
    await client.post(
        "/api/v1/survey/submit",
        json={
            "respondent_name": "CSV Tester",
            "responses": {
                "prereqs": ["Who's affected", "What changed recently"],
                "verify_fix": "Have the user confirm",
                "steps_at_a_time": "5 steps",
                "prioritization": ["Likelihood", "Speed", "Blast radius"],
            },
        },
    )
    res = await client.get("/api/v1/admin/survey-responses/export", headers=admin_auth_headers)
    assert res.status_code == 200
    assert "text/csv" in res.headers["content-type"]
    assert "attachment" in res.headers.get("content-disposition", "")
    body = res.text
    assert "CSV Tester" in body
    assert "Respondent" in body


@pytest.mark.asyncio
async def test_export_survey_responses_requires_admin(client, auth_headers):
    """Non-admin cannot export survey responses."""
    res = await client.get("/api/v1/admin/survey-responses/export", headers=auth_headers)
    assert res.status_code == 403
