"""Insulin regimen mix per ward.

Basal-bolus vs sliding-scale-only vs IV-infusion vs basal-only vs no-insulin.

ADA/KDA guidance:
  - basal-bolus preferred for sustained hyperglycemia in non-critically ill
  - sliding-scale-only is discouraged as sole regimen (ADA: weak/no evidence)
  - IV infusion: ICU first-line for persistent hyperglycemia / DKA / HHS

이 모듈은 참고용·연구용. 실제 처방 결정용 아님.
"""
from __future__ import annotations

from collections import Counter, defaultdict
from dataclasses import dataclass
from typing import Dict, Iterable, List, Tuple

from .ingest import InsulinOrder, Patient


@dataclass
class WardRegimenMix:
    ward: str
    n_orders: int
    pct_basal_bolus: float
    pct_sliding_scale_only: float
    pct_iv_infusion: float
    pct_basal_only: float
    pct_no_insulin: float
    ada_basal_bolus_rate: float  # in non-critical ward only
    sliding_scale_only_penalty: float  # higher = worse (ADA discouraged)


def compute_regimen_mix(patients: Iterable[Patient],
                        orders: Iterable[InsulinOrder]) -> List[WardRegimenMix]:
    patients = list(patients)
    orders = list(orders)
    pid_to_ward = {p.patient_id: p.ward for p in patients}

    by_ward: Dict[str, List[str]] = defaultdict(list)
    for o in orders:
        w = pid_to_ward.get(o.patient_id)
        if w is None:
            continue
        by_ward[w].append(o.regimen)

    out = []
    for w in sorted(by_ward):
        regs = by_ward[w]
        n = len(regs) or 1
        c = Counter(regs)
        bb = c.get("basal-bolus", 0)
        ss = c.get("sliding-scale-only", 0)
        iv = c.get("IV-infusion", 0)
        bo = c.get("basal-only", 0)
        none = c.get("no-insulin", 0)
        is_icu = w in ("MICU", "SICU", "CCU", "NICU")
        # ADA: basal-bolus preferred in non-critical
        ada_bb = 100 * bb / max(1, (bb + ss + bo)) if not is_icu else 100 * bb / max(1, (bb + ss + iv + bo))
        # higher is worse
        ss_penalty = 100 * ss / n
        out.append(WardRegimenMix(
            ward=w,
            n_orders=n,
            pct_basal_bolus=round(100 * bb / n, 1),
            pct_sliding_scale_only=round(100 * ss / n, 1),
            pct_iv_infusion=round(100 * iv / n, 1),
            pct_basal_only=round(100 * bo / n, 1),
            pct_no_insulin=round(100 * none / n, 1),
            ada_basal_bolus_rate=round(ada_bb, 1),
            sliding_scale_only_penalty=round(ss_penalty, 1),
        ))
    return out


def regimen_kda_score(rows: List[WardRegimenMix]) -> Dict[str, float]:
    """ward → KDA-aligned regimen score (0..100), higher = closer to guideline."""
    out = {}
    for r in rows:
        score = max(0.0, min(100.0, r.ada_basal_bolus_rate - 0.6 * r.sliding_scale_only_penalty + 20))
        out[r.ward] = round(score, 1)
    return out
