"""Tests for reports router (/api/reports).

Note: Report generation requires WeasyPrint/Kaleido and Jinja2 templates.
These tests mock the PDF generation to test endpoint plumbing and auth.
"""
from unittest.mock import AsyncMock, patch

import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession

from src.backend.models.orm.user import User
from src.backend.tests.conftest import auth_headers, create_test_recipe


class TestMeasurementReport:
    """GET /api/reports/measurements tests."""

    async def test_generate_measurement_report(
        self,
        client: AsyncClient,
        metrologist_user: User,
        db_session: AsyncSession,
    ):
        """Metrologist can generate a measurement report (mocked PDF)."""
        recipe = await create_test_recipe(
            db_session, metrologist_user.id
        )

        fake_pdf = b"%PDF-1.4 fake content"
        with patch(
            "src.backend.api.routers.reports.generate_measurement_report",
            new_callable=AsyncMock,
            return_value=fake_pdf,
        ):
            resp = await client.get(
                "/api/reports/measurements",
                headers=auth_headers(metrologist_user),
                params={"recipe_id": recipe.id},
            )

        assert resp.status_code == 200
        assert resp.headers["content-type"] == "application/pdf"
        assert b"%PDF" in resp.content

    async def test_report_requires_auth(self, client: AsyncClient):
        """Report endpoints require authentication."""
        resp = await client.get(
            "/api/reports/measurements",
            params={"recipe_id": 1},
        )
        assert resp.status_code == 401


class TestSPCReport:
    """GET /api/reports/spc tests."""

    async def test_generate_spc_report(
        self,
        client: AsyncClient,
        metrologist_user: User,
        db_session: AsyncSession,
    ):
        """Metrologist can generate an SPC report (mocked PDF)."""
        recipe = await create_test_recipe(
            db_session, metrologist_user.id
        )

        # Get subtask_id
        tasks_resp = await client.get(
            f"/api/recipes/{recipe.id}/tasks",
            headers=auth_headers(metrologist_user),
        )
        subtask_id = tasks_resp.json()[0]["subtasks"][0]["id"]

        fake_pdf = b"%PDF-1.4 spc report content"
        with patch(
            "src.backend.api.routers.reports.generate_spc_report",
            new_callable=AsyncMock,
            return_value=fake_pdf,
        ):
            resp = await client.get(
                "/api/reports/spc",
                headers=auth_headers(metrologist_user),
                params={
                    "recipe_id": recipe.id,
                    "subtask_id": subtask_id,
                },
            )

        assert resp.status_code == 200
        assert resp.headers["content-type"] == "application/pdf"

    async def test_spc_report_requires_metrologist(
        self,
        client: AsyncClient,
        maker_user: User,
        db_session: AsyncSession,
    ):
        """Non-Metrologist cannot generate SPC reports."""
        recipe = await create_test_recipe(db_session, maker_user.id)
        resp = await client.get(
            "/api/reports/spc",
            headers=auth_headers(maker_user),
            params={"recipe_id": recipe.id, "subtask_id": 1},
        )
        assert resp.status_code == 403
