from __future__ import annotations

from app.services.risk_rule_flow_diagram import (
    RiskRuleFlowDiagramField,
    RiskRuleFlowDiagramRenderer,
    build_risk_rule_flow_diagram_spec,
)


FIELDS = (
    RiskRuleFlowDiagramField(key="claim.amount", label="申请金额"),
    RiskRuleFlowDiagramField(key="budget.remaining_amount", label="可用预算"),
    RiskRuleFlowDiagramField(key="claim.reason", label="申请事由"),
)


def test_flow_diagram_spec_prefers_flow_model_nodes() -> None:
    spec = build_risk_rule_flow_diagram_spec(
        {"name": "预算余额校验", "metadata": {"condition_summary": "legacy summary"}},
        fields=FIELDS,
        domain_label="差旅费",
        severity="high",
        severity_label="高风险",
        flow_model={
            "nodes": [
                {"id": "start", "type": "start", "title": "开始", "description": "费用申请提交"},
                {
                    "id": "evidence",
                    "type": "evidence",
                    "title": "字段事实",
                    "description": "读取申请金额与可用预算",
                    "fields": ["claim.amount", "budget.remaining_amount"],
                },
                {
                    "id": "amount_exceeds_budget",
                    "type": "decision",
                    "title": "金额超过预算",
                    "description": "申请金额大于可用预算余额",
                },
                {"id": "pass", "type": "pass", "description": "预算充足，继续流转"},
                {"id": "hit", "type": "risk", "description": "进入预算复核"},
            ],
            "metadata": {"hit_logic": "amount_exceeds_budget"},
        },
    )

    assert spec.start == "费用申请提交"
    assert spec.fact_lines[:2] == (
        "A=申请金额[claim.amount]",
        "B=可用预算[budget.remaining_amount]",
    )
    assert spec.condition_lines == ("金额超过预算: 申请金额大于可用预算余额",)
    assert spec.hit_logic == "amount_exceeds_budget"
    svg = RiskRuleFlowDiagramRenderer().render(spec)
    assert "金额超过预算" in svg
    assert "#dc2626" in svg


def test_flow_diagram_spec_falls_back_to_dsl_when_flow_model_missing() -> None:
    spec = build_risk_rule_flow_diagram_spec(
        {
            "name": "重复发票校验",
            "params": {
                "conditions": [
                    {
                        "id": "same_invoice_no_repeated",
                        "operator": "duplicate_value",
                        "fields": ["claim.reason"],
                    }
                ],
                "hit_logic": {"all": ["same_invoice_no_repeated"]},
            },
            "metadata": {"condition_summary": "发票号重复时命中"},
        },
        fields=FIELDS,
        domain_label="通用",
        severity="medium",
        severity_label="中风险",
        flow_model={},
    )

    assert spec.condition_lines == ("same_invoice_no_repeated: 申请事由 出现重复值",)
    assert spec.hit_logic == "same_invoice_no_repeated"
    assert "发票号重复时命中" in spec.basis


def test_flow_diagram_spec_compresses_too_many_decision_nodes() -> None:
    nodes = [{"id": "start", "type": "start", "description": "提交单据"}]
    nodes.extend(
        {
            "id": f"condition_{index}",
            "type": "decision",
            "title": f"判断{index}",
            "description": f"第{index}个判断条件",
        }
        for index in range(1, 7)
    )
    spec = build_risk_rule_flow_diagram_spec(
        {"name": "复杂规则"},
        fields=FIELDS,
        domain_label="通用",
        severity="low",
        severity_label="低风险",
        flow_model={"nodes": nodes},
    )

    assert len(spec.condition_lines) == 4
    assert "另有 2 个判断节点" in spec.condition_lines[-1]
