"""Multi-analyte co-analysis: insulin / C-peptide / glucagon / proinsulin.

Computes:
  - C-peptide:insulin molar ratio (proxy for hepatic clearance / secretion)
  - Counter-regulatory glucagon suppression (basal/high-glucose ratio)
  - iPSC-SC-beta maturation index trajectory across D14/D21/D28 references
  - Trace bundling for plotting (channel-by-channel multi-analyte view)
"""
from __future__ import annotations

import math
from typing import Dict, List

import numpy as np


# ---------------------------------------------------------------------------
# C-peptide : insulin ratio (mass-based, can be converted via assay-specific MW)
# ---------------------------------------------------------------------------
def c_peptide_insulin_ratio(
    cp_values: List[float], ins_values: List[float]
) -> List[float]:
    out = []
    for c, i in zip(cp_values, ins_values):
        if i and not math.isnan(i) and i > 0:
            out.append(c / i)
        else:
            out.append(float("nan"))
    return out


# ---------------------------------------------------------------------------
# glucagon suppression (low/high glucose mean ratio; high should suppress glucagon)
# ---------------------------------------------------------------------------
def glucagon_suppression(
    time_min: List[float], gcg_values: List[float]
) -> Dict[str, float]:
    arr_t = np.array(time_min, dtype=float)
    arr_v = np.array(gcg_values, dtype=float)
    pre = arr_v[(arr_t < 10) & ~np.isnan(arr_v)]
    high = arr_v[(arr_t >= 10) & (arr_t <= 40) & ~np.isnan(arr_v)]
    if pre.size == 0 or high.size == 0 or pre.mean() <= 0:
        return {"basal_mean": float("nan"), "high_mean": float("nan"), "suppression_pct": float("nan")}
    suppression = 100.0 * (1.0 - high.mean() / pre.mean())
    return {
        "basal_mean": float(pre.mean()),
        "high_mean": float(high.mean()),
        "suppression_pct": float(suppression),
    }


# ---------------------------------------------------------------------------
# iPSC-SC-beta maturation index: composite of GSIS ratio + KCl ratio + 1st-phase peak
# ---------------------------------------------------------------------------
# Reference profile inferred from typical Hogrebe/Velazco-Cruz/Pagliuca curves
# (synthetic anchors, not externally fetched).
MATURATION_REFERENCE = {
    "D14": {"gsis_ratio": 1.4, "ksis_ratio": 1.1, "phase1_peak_ng": 7.0},
    "D21": {"gsis_ratio": 2.1, "ksis_ratio": 1.4, "phase1_peak_ng": 12.0},
    "D28": {"gsis_ratio": 2.8, "ksis_ratio": 1.7, "phase1_peak_ng": 18.0},
}
PRIMARY_HUMAN_REFERENCE = {"gsis_ratio": 3.2, "ksis_ratio": 2.0, "phase1_peak_ng": 22.0}


def maturation_index(params: Dict[str, float]) -> Dict[str, float]:
    """Score sample's GSIS/KSIS/peak vs primary human islet reference (= 1.0)."""
    ref = PRIMARY_HUMAN_REFERENCE
    pieces = {
        "gsis_score": params.get("gsis_ratio_16p7_2p8", 0.0) / ref["gsis_ratio"]
        if ref["gsis_ratio"]
        else 0.0,
        "ksis_score": params.get("ksis_ratio_kcl_glucose", 0.0) / ref["ksis_ratio"]
        if ref["ksis_ratio"]
        else 0.0,
        "peak_score": params.get("phase1_peak", 0.0) / ref["phase1_peak_ng"]
        if ref["phase1_peak_ng"]
        else 0.0,
    }
    pieces["composite"] = float(np.nanmean(list(pieces.values())))
    return pieces


def closest_maturation_day(params: Dict[str, float]) -> str:
    """Return D14 / D21 / D28 / mature label closest to observed sample."""
    target_g = params.get("gsis_ratio_16p7_2p8", 0.0)
    best, best_d = float("inf"), "D14"
    for day, ref in MATURATION_REFERENCE.items():
        d = abs(target_g - ref["gsis_ratio"])
        if d < best:
            best, best_d = d, day
    if target_g >= PRIMARY_HUMAN_REFERENCE["gsis_ratio"] - 0.3:
        return "primary-like"
    return best_d
