from decimal import Decimal

from test_purchases import (
    create,
    headers,
    setup_purchase,
)


pytest_plugins = ("test_workspace",)


def test_supplier_payables_and_statement(
    client,
    verified_user,
):
    ctx = setup_purchase(client, verified_user)

    business_id, _, supplier, _, _ = ctx

    purchase = create(
        client,
        verified_user,
        ctx,
        reference="PAYABLE-1",
    ).json()["purchase"]

    received = client.post(
        (
            f"/api/businesses/{business_id}"
            f"/purchases/{purchase['id']}/receive"
        ),
        headers=headers(verified_user),
    )

    assert received.status_code == 200

    payment = client.post(
        (
            f"/api/businesses/{business_id}"
            f"/purchases/{purchase['id']}/payments"
        ),
        json={
            "amount": "20",
            "payment_method": "TRANSFER",
            "reference": "BANK-1",
        },
        headers=headers(verified_user),
    )

    assert payment.status_code == 201

    rows = client.get(
        f"/api/businesses/{business_id}/payables",
        headers=headers(verified_user),
    )

    assert rows.status_code == 200

    data = rows.json()

    assert len(data) == 1
    assert data[0]["id"] == purchase["id"]
    assert data[0]["supplier_id"] == supplier["id"]
    assert Decimal(str(data[0]["balance"])) == Decimal("36")

    statement = client.get(
        (
            f"/api/businesses/{business_id}"
            f"/suppliers/{supplier['id']}/statement"
        ),
        headers=headers(verified_user),
    )

    assert statement.status_code == 200

    body = statement.json()

    assert Decimal(str(body["current_payable"])) == Decimal("36")

    assert [
        entry["event_type"]
        for entry in body["entries"]
    ] == [
        "PURCHASE_RECEIVED",
        "PAYMENT",
    ]

    assert Decimal(
        str(body["entries"][-1]["running_balance"])
    ) == Decimal("36")


def test_payables_report_ignores_drafts_and_paid_purchases(
    client,
    verified_user,
):
    ctx = setup_purchase(client, verified_user)
    business_id = ctx[0]

    open_purchase = create(
        client,
        verified_user,
        ctx,
        reference="PAYABLE-OPEN",
    ).json()["purchase"]

    draft_purchase = create(
        client,
        verified_user,
        ctx,
        reference="PAYABLE-DRAFT",
    ).json()["purchase"]

    assert draft_purchase["lifecycle_status"] == "DRAFT"

    assert client.post(
        (
            f"/api/businesses/{business_id}"
            f"/purchases/{open_purchase['id']}/receive"
        ),
        headers=headers(verified_user),
    ).status_code == 200

    summary = client.get(
        f"/api/businesses/{business_id}/reports/payables",
        headers=headers(verified_user),
    )

    assert summary.status_code == 200

    report = summary.json()

    assert report["purchase_count"] == 1
    assert Decimal(str(report["total"])) == Decimal("56")
    assert Decimal(str(report["outstanding"])) == Decimal("56")

    assert client.post(
        (
            f"/api/businesses/{business_id}"
            f"/purchases/{open_purchase['id']}/payments"
        ),
        json={
            "amount": "56",
            "payment_method": "CASH",
        },
        headers=headers(verified_user),
    ).status_code == 201

    rows = client.get(
        f"/api/businesses/{business_id}/payables",
        headers=headers(verified_user),
    ).json()

    assert rows == []

    after = client.get(
        f"/api/businesses/{business_id}/reports/payables",
        headers=headers(verified_user),
    ).json()

    assert after["purchase_count"] == 0
    assert Decimal(str(after["outstanding"])) == Decimal("0")
