from app.domain.opportunity_flow import build_opportunity_evidence, decide_opportunity_next_action, load_company_profile
from app.domain.opportunity_flow.audit import audit_decisions


def _profile():
    return load_company_profile("blif")


def test_blif_profile_loads_defaults_and_labels():
    profile = _profile()
    assert profile.company == "blif"
    assert profile.defaults["payment_terms"] == "before_shipping"
    assert profile.defaults["delivery_terms"] == "carrier"
    assert profile.action_label("CONFIRM_PAYMENT") == "Confirmar pagamento"
    assert profile.documents["quote"]["label"] == "Orçamento"
    assert profile.documents["invoice"]["label"] == "Fatura"


def test_quote_before_shipping_requires_confirm_payment_before_invoice():
    evidence = build_opportunity_evidence(
        {"id": "opp-1", "stage": "QUOTE_SENT", "metadata": {"payment_terms": "before_shipping"}},
        linked_customer={"id": "c1", "tax_id": "123", "billing_email": "a@b.pt", "address": "Rua", "postal_code": "1000", "city": "Lisboa"},
        linked_documents=[{"id": "q1", "document_kind": "quotation", "document_number": "ORC.ORC2026.177", "total_amount": 202.95}],
        operation_snapshot={"links": [], "cards": []},
        fiscal_data_complete=True,
    )
    decision = decide_opportunity_next_action(evidence, _profile())
    assert decision.next_action.code == "CONFIRM_PAYMENT"
    assert decision.next_action.document_number == "ORC.ORC2026.177"
    assert "antes da fatura" in decision.next_action.description or "antes de emitir fatura" in decision.next_action.description


def test_payment_confirmed_without_invoice_sends_invoice():
    evidence = build_opportunity_evidence(
        {"id": "opp-2", "stage": "PAYMENT_CONFIRMED", "metadata": {"payment_terms": "before_shipping"}},
        linked_customer={"id": "c1", "tax_id": "123", "billing_email": "a@b.pt", "address": "Rua", "postal_code": "1000", "city": "Lisboa"},
        linked_documents=[{"id": "q1", "document_kind": "quotation", "document_number": "ORC.ORC2026.177"}],
        operation_snapshot={"links": [{"system": "clientflow", "external_type": "payment", "status": "confirmed"}], "cards": []},
        fiscal_data_complete=True,
    )
    decision = decide_opportunity_next_action(evidence, _profile())
    assert decision.next_action.code == "SEND_INVOICE"
    assert decision.next_action.label == "Enviar fatura ao cliente"


def test_payment_invoice_pending_send_keeps_send_invoice_before_waiting_production():
    evidence = build_opportunity_evidence(
        {"id": "opp-3", "stage": "PAYMENT_CONFIRMED", "metadata": {"payment_terms": "before_shipping"}},
        linked_customer={"id": "c1", "tax_id": "123", "billing_email": "a@b.pt", "address": "Rua", "postal_code": "1000", "city": "Lisboa"},
        linked_documents=[
            {"id": "q1", "document_kind": "quotation", "document_number": "ORC.ORC2026.177"},
            {"id": "i1", "document_kind": "invoice", "document_number": "FA.FA2026.114", "status": "open"},
        ],
        tasks=[{"id": "t1", "status": "pending", "action_code": "SEND_INVOICE", "action": "Enviar fatura"}],
        operation_snapshot={
            "links": [{"system": "clientflow", "external_type": "payment", "status": "confirmed"}],
            "cards": [{"key": "odoo_production", "status": "in_progress"}],
        },
        fiscal_data_complete=True,
    )
    decision = decide_opportunity_next_action(evidence, _profile())
    assert decision.next_action.code == "SEND_INVOICE"
    assert decision.next_action.target_url == "/tasks/t1"
    assert "Enviar PDF" in decision.next_action.description


def test_payment_invoice_sent_and_odoo_production_waits_production_not_send_invoice():
    evidence = build_opportunity_evidence(
        {"id": "opp-3b", "stage": "PAYMENT_CONFIRMED", "metadata": {"payment_terms": "before_shipping"}},
        linked_customer={"id": "c1", "tax_id": "123", "billing_email": "a@b.pt", "address": "Rua", "postal_code": "1000", "city": "Lisboa"},
        linked_documents=[
            {"id": "q1", "document_kind": "quotation", "document_number": "ORC.ORC2026.177"},
            {"id": "i1", "document_kind": "invoice", "document_number": "FA.FA2026.114", "sent": True},
        ],
        operation_snapshot={
            "links": [{"system": "clientflow", "external_type": "payment", "status": "confirmed"}],
            "cards": [{"key": "odoo_physical_status", "status": "created", "payload": {"label": "Em produção/preparação", "ready_to_ship": False, "next_action": "Aguardar conclusão da produção/preparação no Odoo."}}],
        },
        fiscal_data_complete=True,
    )
    decision = decide_opportunity_next_action(evidence, _profile())
    assert decision.next_action.code == "WAIT_PRODUCTION"
    assert decision.next_action.label == "Aguardar produção"
    assert decision.financial_state == "payment_confirmed"
    assert audit_decisions([decision]) == []


def test_after_delivery_shipped_without_payment_followup_payment():
    evidence = build_opportunity_evidence(
        {"id": "opp-4", "stage": "SHIPMENT_CREATED", "metadata": {"payment_terms": "after_delivery"}},
        linked_customer={"id": "c1", "tax_id": "123", "billing_email": "a@b.pt", "address": "Rua", "postal_code": "1000", "city": "Lisboa"},
        linked_documents=[{"id": "q1", "document_kind": "quotation", "document_number": "ORC.ORC2026.200"}],
        operation_snapshot={"links": [], "cards": [{"key": "packlink_shipment", "status": "created"}]},
        fiscal_data_complete=True,
    )
    decision = decide_opportunity_next_action(evidence, _profile())
    assert decision.next_action.code == "FOLLOW_UP_PAYMENT"


def test_fiscal_conflict_blocks_financial_actions():
    evidence = build_opportunity_evidence(
        {"id": "opp-5", "stage": "QUOTE_SENT", "metadata": {"has_nif_conflict": True}},
        linked_customer={"id": "c1", "tax_id": "123"},
        linked_documents=[{"id": "q1", "document_kind": "quotation", "document_number": "ORC.ORC2026.177"}],
    )
    decision = decide_opportunity_next_action(evidence, _profile())
    assert decision.next_action.code == "REVIEW"
    blocked = {a.code for a in decision.blocked_actions}
    assert {"CONFIRM_PAYMENT", "SEND_INVOICE", "CREATE_JASMIN_QUOTE"} <= blocked


def test_after_delivery_invoice_without_payment_allows_prepare_odoo_before_payment():
    evidence = build_opportunity_evidence(
        {"id": "opp-after-delivery", "stage": "INVOICE_SENT", "metadata": {"payment_terms": "after_delivery"}},
        linked_customer={"id": "c1", "tax_id": "123", "billing_email": "a@b.pt", "address": "Rua", "postal_code": "1000", "city": "Lisboa"},
        linked_documents=[
            {"id": "q1", "document_kind": "quotation", "document_number": "ORC.ORC2026.194", "status": "completed"},
            {"id": "i1", "document_kind": "invoice", "document_number": "FA.FA2026.129", "status": "open"},
        ],
        operation_snapshot={"links": [], "cards": []},
        fiscal_data_complete=True,
    )
    decision = decide_opportunity_next_action(evidence, _profile())
    assert decision.next_action.code == "PREPARE_ORDER"
    assert "sem pagamento prévio" in decision.reason or "sem exigir pagamento" in decision.next_action.description
