"""v4.9.20: fiscal customer identity is not purchase identity."""

import sys
import types

if "sqlalchemy" not in sys.modules:
    sqlalchemy = types.ModuleType("sqlalchemy")
    sqlalchemy.text = lambda sql: sql
    sys.modules["sqlalchemy"] = sqlalchemy

if "app.db" not in sys.modules:
    app_db = types.ModuleType("app.db")
    app_db.engine = object()
    sys.modules["app.db"] = app_db

if "app.action_catalog" not in sys.modules:
    action_catalog = types.ModuleType("app.action_catalog")
    action_catalog.get_action_config = lambda code: {"route": "rever", "action": code, "action_required": True, "safe_to_post": False}
    sys.modules["app.action_catalog"] = action_catalog

from app import reconciliation_service as svc


def _jasmin_doc(id_, external_type, number, date, amount):
    return {
        "id": id_,
        "source_system": "jasmin",
        "external_type": external_type,
        "title": f"Documento Jasmin · {number}",
        "customer_name": "ACZCO BRAGA ENERGY, LDA",
        "customer_tax_id": "517249200",
        "document_number": number,
        "document_date": date,
        "amount": amount,
        "currency": "EUR",
        "operation_suggestions": [],
    }


def test_same_company_two_jasmin_quotes_stay_as_two_purchase_candidates(monkeypatch):
    monkeypatch.setattr(
        svc,
        "list_reconciliation_items",
        lambda *, status, limit, days: [
            _jasmin_doc("quote-154", "jasmin_quotation", "ORC.ORC2026.154", "2026-06-03", "638.60"),
            _jasmin_doc("quote-160", "jasmin_quotation", "ORC.ORC2026.160", "2026-06-06", "190.00"),
        ],
    )

    candidates = svc.list_reconciliation_process_candidates(status="open", days=7, limit=10)

    assert len(candidates) == 2
    keys = {candidate["operation_key"] for candidate in candidates}
    assert "jasmin_quotation:ORC.ORC2026.154" in keys
    assert "jasmin_quotation:ORC.ORC2026.160" in keys
    assert {tuple(candidate["item_ids"]) for candidate in candidates} == {("quote-154",), ("quote-160",)}


def test_quote_and_invoice_with_same_amount_and_near_date_can_form_one_purchase(monkeypatch):
    monkeypatch.setattr(
        svc,
        "list_reconciliation_items",
        lambda *, status, limit, days: [
            _jasmin_doc("quote-154", "jasmin_quotation", "ORC.ORC2026.154", "2026-06-03", "638.60"),
            _jasmin_doc("invoice-80", "jasmin_invoice", "FA2026.80", "2026-06-05", "638.60"),
            _jasmin_doc("quote-160", "jasmin_quotation", "ORC.ORC2026.160", "2026-06-20", "190.00"),
        ],
    )

    candidates = svc.list_reconciliation_process_candidates(status="open", days=30, limit=10)

    grouped = {candidate["operation_key"]: set(candidate["item_ids"]) for candidate in candidates}
    assert grouped["jasmin_quotation:ORC.ORC2026.154"] == {"quote-154", "invoice-80"}
    assert grouped["jasmin_quotation:ORC.ORC2026.160"] == {"quote-160"}


def test_payment_proof_assigns_only_when_order_match_is_unambiguous(monkeypatch):
    order_a = {
        "id": "sale-279",
        "source_system": "odoo",
        "external_type": "odoo_sale_order",
        "title": "Venda Odoo sem oportunidade · S00279",
        "customer_name": "ACZCO BRAGA ENERGY, LDA",
        "customer_tax_id": "517249200",
        "document_number": "S00279",
        "document_date": "2026-06-05",
        "amount": "638.60",
        "currency": "EUR",
        "payload": {"record": {"name": "S00279", "invoice_status": "to invoice"}},
        "operation_suggestions": [],
    }
    order_b = {**order_a, "id": "sale-280", "document_number": "S00280", "amount": "190.00", "payload": {"record": {"name": "S00280", "invoice_status": "to invoice"}}}
    proof = {
        "id": "proof-279",
        "source_system": "email",
        "external_type": "payment_proof",
        "title": "Comprovativo recebido",
        "customer_name": "ACZCO BRAGA ENERGY, LDA",
        "customer_tax_id": "517249200",
        "document_number": "comprovativo-279",
        "document_date": "2026-06-06",
        "amount": "638.60",
        "currency": "EUR",
        "operation_suggestions": [],
    }
    monkeypatch.setattr(svc, "list_reconciliation_items", lambda *, status, limit, days: [order_a, order_b, proof])

    candidates = svc.list_reconciliation_process_candidates(status="open", days=7, limit=10)

    grouped = {candidate["operation_key"]: set(candidate["item_ids"]) for candidate in candidates}
    assert grouped["odoo_sale_order:S00279"] == {"sale-279", "proof-279"}
    assert grouped["odoo_sale_order:S00280"] == {"sale-280"}
