"""v4.9.11 regression tests for Odoo name-only reconciliation.

Odoo customers may not have VAT/NIF filled in.  Reconciliation should still be
able to suggest/link by normalized company name and should not abort the whole
process candidate list when an individual suggestion lookup fails.
"""

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 test_company_name_normalization_matches_odoo_without_nif():
    score = svc._name_match_score(
        "ELEGANTLEGACY, LDA VALONGO Portugal",
        "Elegantlegacy Lda",
        "Oportunidade · elegantlegacy",
    )
    assert score >= 35


def test_single_odoo_sale_without_nif_becomes_process_candidate(monkeypatch):
    monkeypatch.setattr(
        svc,
        "list_reconciliation_items",
        lambda *, status, limit, days: [
            {
                "id": "odoo-sale-274",
                "source_system": "odoo",
                "external_type": "odoo_sale_order",
                "title": "Venda Odoo sem oportunidade · S00274",
                "customer_name": "ELEGANTLEGACY, LDA",
                "customer_tax_id": "",
                "customer_email": "",
                "document_number": "S00274",
                "document_date": "2026-06-02",
                "amount": "537.00",
                "currency": "EUR",
                "operation_suggestions": [],
            }
        ],
    )

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

    assert len(candidates) == 1
    candidate = candidates[0]
    assert candidate["match_key"] == "name"
    assert candidate["confidence"] == "alta"
    assert candidate["identity_reason"] == "nome fiscal"
    assert candidate["customer_name"] == "ELEGANTLEGACY, LDA"
    assert candidate["suggested_stage"] == "ODOO_ORDER_CREATED"
    assert candidate["suggested_action"] == "SEND_INVOICE"
    assert candidate["item_ids"] == ["odoo-sale-274"]


def test_list_process_candidates_is_resilient_when_item_query_fails(monkeypatch):
    def fail_listing(*, status, limit, days):
        raise RuntimeError("simulated db lookup failure")

    monkeypatch.setattr(svc, "list_reconciliation_items", fail_listing)

    assert svc.list_reconciliation_process_candidates(status="open", days=7, limit=10) == []


def test_person_name_only_is_not_high_confidence_identity():
    confidence, reason = svc._process_group_identity_label(
        "name",
        [{"customer_name": "Bruno Oliveira", "customer_tax_id": "", "source_system": "odoo"}],
    )

    assert confidence == "média"
    assert reason == "nome"
