"""
rules.py
Signal — STTIL Solutions

Format-tolerant readers for payer_rules.json plus the stable rule-ID registry
(build plan 02, item P2; design: readiness-model-design-phase2 section 3.1).

A rule value may be FLAT (legacy: `"visit_renewal_days": 180`) or WRAPPED with
its citation (`"visit_renewal_days": {"value": 180, "rule_id": "R001"}`).
Both engines read through these helpers so the JSON format can carry citation
IDs without breaking either reader.

RULE IDS ARE STABLE — never change an ID after shipping. The ID names the rule
KIND; the plan type plus the value together are the citation.
"""

from __future__ import annotations

from typing import Optional

# Universal claim/coverage requirements per LCD L33822, independent of plan
# type. They live in code (no plan-type dependency) but carry rule IDs for
# citation consistency.
UNIVERSAL_RULE_IDS = {"swo": "R100", "visit": "R101", "diagnosis": "R102"}

# Plan-scoped keys in payer_rules.json and their registry IDs.
PLAN_KEY_RULE_IDS = {
    "visit_renewal_days": "R001",
    "refill_window_days": "R002",
    "pa_required": "R003",
    "pecos_required": "R004",
}


def rule_value(cfg: Optional[dict], key: str, default=None):
    """Read a rule value, accepting flat (180) and wrapped
    ({'value': 180, 'rule_id': 'R001'}) formats."""
    if not cfg:
        return default
    raw = cfg.get(key, default)
    if isinstance(raw, dict) and "value" in raw:
        return raw["value"]
    return raw


def rule_id_for(cfg: Optional[dict], key: str) -> Optional[str]:
    """The citation ID for a plan-scoped rule: from the wrapped config when
    present, else the registry default for that key."""
    raw = cfg.get(key) if cfg else None
    if isinstance(raw, dict) and "rule_id" in raw:
        return raw["rule_id"]
    return PLAN_KEY_RULE_IDS.get(key)
