"""Tests for the new PUT /api/invoices/{inv_id} edit endpoint."""
from tests.conftest import BASE_URL


def _create_sample_invoice(session, company_id, *, party_name="EDIT TEST PARTY"):
    payload = {
        "type": "sale",
        "party_name": party_name,
        "party_state": "Goa",
        "invoice_date": "2026-05-30",
        "lines": [
            {"name": "Widget A", "qty": 2, "unit": "PCS", "rate": 100, "gst_rate": 18, "discount": 0},
            {"name": "Widget B", "qty": 1, "unit": "PCS", "rate": 200, "gst_rate": 18, "discount": 0},
        ],
        "extra_discount": 0,
        "round_off": 0,
        "tax_inclusive": False,
        "payment_received": 0,
        "payment_mode": "Cash",
        "status": "unpaid",
    }
    r = session.post(f"{BASE_URL}/api/invoices?company_id={company_id}", json=payload, timeout=30)
    assert r.status_code == 200, r.text
    return r.json()


def test_put_invoice_updates_notes_and_lines(admin_session, default_company_id):
    inv = _create_sample_invoice(admin_session, default_company_id, party_name="PUT-NOTES")
    inv_id = inv["id"]
    payload = {
        "type": "sale",
        "party_name": "PUT-NOTES UPDATED",
        "party_state": "Goa",
        "invoice_date": "2026-05-30",
        "notes": "edited via PUT",
        "lines": [
            {"name": "Widget A", "qty": 3, "unit": "PCS", "rate": 150, "gst_rate": 18, "discount": 0},
        ],
        "extra_discount": 0, "round_off": 0, "tax_inclusive": False,
        "payment_received": 0, "payment_mode": "Cash", "status": "unpaid",
    }
    r = admin_session.put(f"{BASE_URL}/api/invoices/{inv_id}", json=payload, timeout=30)
    assert r.status_code == 200, r.text
    out = r.json()
    assert out["invoice_no"] == inv["invoice_no"], "invoice_no must be preserved"
    assert out["notes"] == "edited via PUT"
    assert out["party_name"] == "PUT-NOTES UPDATED"
    assert len(out["lines"]) == 1
    assert out["lines"][0]["qty"] == 3
    assert out["updated_by"]
    # Clean up
    admin_session.delete(f"{BASE_URL}/api/invoices/{inv_id}", timeout=30)


def test_put_invoice_recalculates_totals(admin_session, default_company_id):
    inv = _create_sample_invoice(admin_session, default_company_id, party_name="PUT-CALC")
    original_total = inv["total"]
    inv_id = inv["id"]
    # Double the quantities
    payload = {
        "type": "sale",
        "party_name": "PUT-CALC",
        "party_state": "Goa",
        "invoice_date": "2026-05-30",
        "lines": [
            {"name": "Widget A", "qty": 4, "unit": "PCS", "rate": 100, "gst_rate": 18, "discount": 0},
            {"name": "Widget B", "qty": 2, "unit": "PCS", "rate": 200, "gst_rate": 18, "discount": 0},
        ],
        "extra_discount": 0, "round_off": 0, "tax_inclusive": False,
        "payment_received": 0, "payment_mode": "Cash", "status": "unpaid",
    }
    r = admin_session.put(f"{BASE_URL}/api/invoices/{inv_id}", json=payload, timeout=30)
    assert r.status_code == 200, r.text
    out = r.json()
    assert out["total"] == round(original_total * 2, 2), f"{out['total']} != {original_total * 2}"
    admin_session.delete(f"{BASE_URL}/api/invoices/{inv_id}", timeout=30)


def test_put_invoice_404_for_missing_id(admin_session, default_company_id):
    payload = {
        "type": "sale", "party_name": "x", "party_state": "Goa", "invoice_date": "2026-05-30",
        "lines": [{"name": "x", "qty": 1, "unit": "PCS", "rate": 1, "gst_rate": 0, "discount": 0}],
        "extra_discount": 0, "round_off": 0, "tax_inclusive": False,
        "payment_received": 0, "payment_mode": "Cash", "status": "unpaid",
    }
    r = admin_session.put(f"{BASE_URL}/api/invoices/000000000000000000000000", json=payload, timeout=30)
    assert r.status_code == 404


def test_put_invoice_status_recomputed_on_payment(admin_session, default_company_id):
    inv = _create_sample_invoice(admin_session, default_company_id, party_name="PUT-STATUS")
    assert inv["status"] == "unpaid"
    inv_id = inv["id"]
    payload = {
        "type": "sale",
        "party_name": "PUT-STATUS",
        "party_state": "Goa",
        "invoice_date": "2026-05-30",
        "lines": [
            {"name": "Widget A", "qty": 2, "unit": "PCS", "rate": 100, "gst_rate": 18, "discount": 0},
            {"name": "Widget B", "qty": 1, "unit": "PCS", "rate": 200, "gst_rate": 18, "discount": 0},
        ],
        "extra_discount": 0, "round_off": 0, "tax_inclusive": False,
        "payment_received": 1000,    # over-pay → status should flip to paid
        "payment_mode": "Cash", "status": "unpaid",
    }
    r = admin_session.put(f"{BASE_URL}/api/invoices/{inv_id}", json=payload, timeout=30)
    assert r.status_code == 200
    assert r.json()["status"] == "paid"
    admin_session.delete(f"{BASE_URL}/api/invoices/{inv_id}", timeout=30)
