"""Regression tests for the webhook `/printer/{id}/start` route.

The previous implementation called `printer_manager.start_print()` directly
with `queue_item.archive_id` (an int) as the filename arg and no print
options, and used `await` on a non-async function. That route 500'd on
every invocation. The fix mirrors `POST /print-queue/{item_id}/start`:
clear the next pending item's `manual_start` so the scheduler picks it up
with the queue's stored options (timelapse, bed_levelling, etc.) intact.
"""

import pytest
from httpx import AsyncClient


@pytest.fixture
async def api_key_data(async_client: AsyncClient, db_session):
    """Create an API key with control_printer permission."""
    from backend.app.core.auth import generate_api_key
    from backend.app.models.api_key import APIKey

    full_key, key_hash, key_prefix = generate_api_key()
    api_key = APIKey(
        name="webhook-test-key",
        key_hash=key_hash,
        key_prefix=key_prefix,
        can_queue=True,
        can_control_printer=True,
        can_read_status=True,
        enabled=True,
    )
    db_session.add(api_key)
    await db_session.commit()
    return full_key


@pytest.fixture
async def printer_with_queue(db_session):
    """Create a printer and a pending queue item with manual_start=True."""
    from backend.app.models.print_queue import PrintQueueItem
    from backend.app.models.printer import Printer

    printer = Printer(
        name="WebhookTest",
        ip_address="192.168.1.42",
        access_code="12345678",
        serial_number="00M00A000000000",
        model="P1S",
    )
    db_session.add(printer)
    await db_session.commit()

    item = PrintQueueItem(
        printer_id=printer.id,
        position=1,
        status="pending",
        manual_start=True,
        timelapse=True,
        bed_levelling=True,
        flow_cali=False,
        vibration_cali=True,
        layer_inspect=False,
        use_ams=True,
    )
    db_session.add(item)
    await db_session.commit()
    return printer, item


class TestWebhookStartPrint:
    @pytest.mark.asyncio
    @pytest.mark.integration
    async def test_clears_manual_start_on_next_pending_item(
        self, async_client: AsyncClient, db_session, api_key_data, printer_with_queue
    ):
        """The webhook flips manual_start to False so the scheduler picks it up.

        Pre-fix the route called `printer_manager.start_print()` directly
        with no options and `archive_id` (int) as the filename — 500'd on
        every invocation. Now it mirrors the regular `/print-queue/{id}/start`
        affordance: scheduler dispatch handles FTP upload and all print
        options via the queue's stored fields.
        """
        printer, item = printer_with_queue

        resp = await async_client.post(
            f"/api/v1/webhook/printer/{printer.id}/start",
            headers={"X-API-Key": api_key_data},
        )

        assert resp.status_code == 200, resp.text
        assert resp.json()["queue_item_id"] == item.id

        await db_session.refresh(item)
        assert item.manual_start is False, "manual_start must be cleared so scheduler dispatches"
        # Stored options must be untouched so the scheduler picks the user's choice.
        assert item.timelapse is True
        assert item.bed_levelling is True
        assert item.vibration_cali is True

    @pytest.mark.asyncio
    @pytest.mark.integration
    async def test_returns_404_when_no_pending_items(self, async_client: AsyncClient, db_session, api_key_data):
        from backend.app.models.printer import Printer

        printer = Printer(
            name="EmptyQueue",
            ip_address="192.168.1.43",
            access_code="12345678",
            serial_number="00M00A000000001",
            model="P1S",
        )
        db_session.add(printer)
        await db_session.commit()

        resp = await async_client.post(
            f"/api/v1/webhook/printer/{printer.id}/start",
            headers={"X-API-Key": api_key_data},
        )

        assert resp.status_code == 404
        assert "No pending prints" in resp.json()["detail"]

    @pytest.mark.asyncio
    @pytest.mark.integration
    async def test_returns_404_when_printer_does_not_exist(self, async_client: AsyncClient, api_key_data):
        resp = await async_client.post(
            "/api/v1/webhook/printer/99999/start",
            headers={"X-API-Key": api_key_data},
        )
        assert resp.status_code == 404
