"""Firm inbox invoices list — paginated, filterable, firm-only."""

from __future__ import annotations

from fastapi.testclient import TestClient

from app.main import app
from app.services import users as user_service
from app.store import Invoice, Suggestion, store

client = TestClient(app)


def _firm_email(prefix: str) -> str:
    email = f"firm-inbox-{prefix}@test.com"
    user_service.ensure_user(platform="firm", email=email, name="Firm User")
    return email


def _add_invoice(
    *,
    client_id: str,
    file: str,
    status: str = "Needs review",
    supplier: str = "Acme",
    number: str = "INV-1",
    confidence: float = 70,
    uploaded_at: str = "2026-08-17",
    total: float = 100,
) -> Invoice:
    invoice = Invoice(
        id=store._next_id("INV"),  # noqa: SLF001
        file=file,
        clientId=client_id,
        supplier=supplier,
        number=number,
        invoiceDate=uploaded_at,
        dueDate="",
        vatAmount=0,
        total=total,
        currency="EUR",
        paymentRef="",
        uploadedAt=uploaded_at,
        confidence=confidence,
        status=status,
        lines=[],
        suggestion=Suggestion(
            ledger="",
            vatCode="",
            category="",
            relation="",
            reasoning="",
        ),
        ocrText="heavy-ocr-should-not-leak",
    )
    store.state.invoices.insert(0, invoice)
    store._persist()  # noqa: SLF001
    return invoice


def test_firm_can_list_invoices_with_pagination():
    firm_email = _firm_email("page")
    created = store.create_client("Inbox Pagination Co")
    ids = []
    for index in range(25):
        invoice = _add_invoice(
            client_id=created.id,
            file=f"invoice-{index}.pdf",
            status="Needs review",
            uploaded_at=f"2026-08-{(index % 28) + 1:02d}",
        )
        ids.append(invoice.id)

    first = client.get(
        f"/api/v1/invoices?platform=firm&email={firm_email}&page=1&page_size=10&status=all"
    )
    assert first.status_code == 200
    body = first.json()
    assert len(body["items"]) == 10
    assert body["page"] == 1
    assert body["page_size"] == 10
    assert body["total"] >= 25
    assert body["total_pages"] >= 3
    assert body["has_any"] is True
    assert "ocrText" not in body["items"][0]
    assert body["items"][0]["clientName"] == "Inbox Pagination Co"

    second = client.get(
        f"/api/v1/invoices?platform=firm&email={firm_email}&page=2&page_size=10&status=all"
    )
    assert second.status_code == 200
    page_two = second.json()
    assert len(page_two["items"]) == 10
    first_ids = {item["id"] for item in body["items"]}
    second_ids = {item["id"] for item in page_two["items"]}
    assert first_ids.isdisjoint(second_ids)
    assert any(item_id in ids for item_id in second_ids)


def test_search_and_status_filter_before_pagination():
    firm_email = _firm_email("filters")
    created = store.create_client("Filter Co")
    match = _add_invoice(
        client_id=created.id,
        file="acme-bill.pdf",
        supplier="Acme Supplies",
        status="Needs review",
        confidence=90,
    )
    _add_invoice(
        client_id=created.id,
        file="other.pdf",
        supplier="Other",
        status="Approved",
        confidence=40,
    )

    res = client.get(
        f"/api/v1/invoices?platform=firm&email={firm_email}&search=acme&status=Needs%20review&page=1&page_size=20"
    )
    assert res.status_code == 200
    body = res.json()
    assert body["total"] >= 1
    assert any(item["id"] == match.id for item in body["items"])
    assert all("acme" in f"{item['file']} {item['supplier']}".lower() for item in body["items"])
    assert all(item["status"] == "Needs review" for item in body["items"])


def test_client_filter_scopes_results():
    firm_email = _firm_email("client-filter")
    client_a = store.create_client("Client A Inbox")
    client_b = store.create_client("Client B Inbox")
    inv_a = _add_invoice(client_id=client_a.id, file="a.pdf")
    inv_b = _add_invoice(client_id=client_b.id, file="b.pdf")

    res = client.get(
        f"/api/v1/invoices?platform=firm&email={firm_email}&client={client_a.id}&status=all&page=1&page_size=50"
    )
    assert res.status_code == 200
    ids = {item["id"] for item in res.json()["items"]}
    assert inv_a.id in ids
    assert inv_b.id not in ids


def test_queue_filter_excludes_approved():
    firm_email = _firm_email("queue")
    created = store.create_client("Queue Co")
    queued = _add_invoice(client_id=created.id, file="queue.pdf", status="Needs review")
    approved = _add_invoice(client_id=created.id, file="done.pdf", status="Approved")

    res = client.get(
        f"/api/v1/invoices?platform=firm&email={firm_email}&status=queue&page=1&page_size=50"
    )
    assert res.status_code == 200
    ids = {item["id"] for item in res.json()["items"]}
    assert queued.id in ids
    assert approved.id not in ids


def test_client_portal_cannot_list_invoices():
    client_email = "portal-inbox@test.com"
    created = store.create_client("Portal Inbox", email=client_email)
    user_service.ensure_user(
        platform="client",
        email=client_email,
        name="Portal User",
        client_id=created.id,
    )
    res = client.get(f"/api/v1/invoices?platform=client&email={client_email}&page=1&page_size=20")
    assert res.status_code == 403


def test_unauthenticated_firm_list_is_rejected():
    res = client.get("/api/v1/invoices?platform=firm&email=missing-inbox@test.com&page=1&page_size=20")
    assert res.status_code == 403


def test_page_size_is_capped():
    firm_email = _firm_email("size")
    res = client.get(f"/api/v1/invoices?platform=firm&email={firm_email}&page=1&page_size=100")
    assert res.status_code == 422
