"""Triangulation-targeted follow-up study design cards.

Maps each suspected bias to one or more of seven canonical follow-up designs.
Returns design cards with primary endpoint, estimated sample size, follow-up
duration, and key hypothesis text.
"""
from __future__ import annotations

from typing import Any

DESIGN_CATALOG = [
    {
        "design_type": "active_comparator_new_user",
        "name": "Active-comparator new-user observational",
        "addresses": ["confounding_by_indication", "healthy_user_bias", "protopathic_bias"],
        "primary_endpoint_template": "Time to {outcome} (intention-to-treat) vs an active comparator with similar indication",
        "default_n": 50000,
        "default_followup_years": 3,
        "rationale": (
            "Restricts to new initiators of the index drug vs an active comparator "
            "with the same indication, reducing channeling bias and prevalent-user bias."
        ),
    },
    {
        "design_type": "target_mr_pqtl",
        "name": "Target-MR using pQTL instrumental variable",
        "addresses": ["off_target", "confounding_by_indication", "healthy_user_bias"],
        "primary_endpoint_template": "MR estimate of {drug} target on {outcome} using pQTL of {target}",
        "default_n": 400000,
        "default_followup_years": 0,
        "rationale": (
            "Uses cis-pQTL of the canonical drug target as an instrument, isolating "
            "the on-target effect from confounded observational associations."
        ),
    },
    {
        "design_type": "negative_control_outcome",
        "name": "Negative control outcome study",
        "addresses": ["detection_bias", "confounding_by_indication"],
        "primary_endpoint_template": "Risk of pre-specified negative control outcome under {drug}",
        "default_n": 100000,
        "default_followup_years": 2,
        "rationale": (
            "If a drug appears 'protective' against an outcome with no plausible "
            "mechanism, residual confounding / detection bias is the likely driver."
        ),
    },
    {
        "design_type": "factorial_2x2_rct",
        "name": "2x2 factorial RCT",
        "addresses": ["off_target", "external_validity"],
        "primary_endpoint_template": "{outcome} under {drug} vs control x background therapy strata",
        "default_n": 8000,
        "default_followup_years": 3,
        "rationale": (
            "Factorial design separates the effect of {drug} from interactions with "
            "another standard-of-care agent or subgroup factor."
        ),
    },
    {
        "design_type": "n_of_1_crossover",
        "name": "N-of-1 crossover",
        "addresses": ["external_validity", "dose_translation"],
        "primary_endpoint_template": "Within-subject change in {outcome} surrogate during ABAB blocks of {drug}",
        "default_n": 60,
        "default_followup_years": 1,
        "rationale": (
            "Quantifies individual responsiveness and confirms biological "
            "plausibility at clinically achievable exposures."
        ),
    },
    {
        "design_type": "bariatric_natural_experiment",
        "name": "Natural-experiment / instrumental-variable cohort",
        "addresses": ["confounding_by_indication", "healthy_user_bias", "survivor_bias"],
        "primary_endpoint_template": "{outcome} after a discontinuity-based assignment to {drug} (e.g. policy cutoff or surgery eligibility)",
        "default_n": 30000,
        "default_followup_years": 5,
        "rationale": (
            "Uses an exogenous trigger (policy change, BMI threshold, geographic "
            "variation) to mimic randomization in real-world data."
        ),
    },
    {
        "design_type": "bridging_ex_vivo",
        "name": "Bridging ex vivo at human-achievable concentrations",
        "addresses": ["dose_translation"],
        "primary_endpoint_template": "Effect of {drug} on relevant tissue at C_max plasma concentration",
        "default_n": 0,
        "default_followup_years": 0,
        "rationale": (
            "Repeats the positive ex vivo experiment at drug concentrations that "
            "are actually achievable in patients, testing whether dose translation "
            "explains the discordance."
        ),
    },
]


def recommend_designs(
    diagnosed_biases: list[dict[str, Any]],
    drug: str,
    outcome: str,
    *,
    target: str = "the canonical drug target",
    max_cards: int = 7,
) -> list[dict[str, Any]]:
    """Return ranked design cards for a discordant pair.

    Scoring: each design card gets a score = sum of (bias_score) over biases
    in its `addresses` set that appear in `diagnosed_biases`. Cards with zero
    matches still appear (lower priority) so the user always gets the full
    7-card deck, which is the spec.
    """
    bias_scores = {b["bias_type"]: b["score"] for b in diagnosed_biases}

    cards: list[dict[str, Any]] = []
    for spec in DESIGN_CATALOG:
        match_score = sum(
            bias_scores.get(b, 0) for b in spec["addresses"]
        )
        matched = [b for b in spec["addresses"] if b in bias_scores]
        card = {
            "design_type": spec["design_type"],
            "name": spec["name"],
            "primary_endpoint": spec["primary_endpoint_template"].format(
                drug=drug, outcome=outcome, target=target
            ),
            "estimated_sample_size": spec["default_n"],
            "follow_up_years": spec["default_followup_years"],
            "addresses_biases": spec["addresses"],
            "matched_biases": matched,
            "match_score": match_score,
            "rationale": spec["rationale"].format(drug=drug, outcome=outcome, target=target),
            "key_hypothesis": _hypothesis(spec["design_type"], drug, outcome, target),
        }
        cards.append(card)

    cards.sort(key=lambda c: -c["match_score"])
    return cards[:max_cards]


def _hypothesis(design_type: str, drug: str, outcome: str, target: str) -> str:
    if design_type == "active_comparator_new_user":
        return (
            f"H: Among new initiators with the same indication, {drug} versus an "
            f"active comparator yields {outcome} risk consistent with the RCT effect."
        )
    if design_type == "target_mr_pqtl":
        return (
            f"H: Genetically proxied inhibition of {target} reduces (or does not "
            f"change) {outcome} risk, isolating on-target causal effect."
        )
    if design_type == "negative_control_outcome":
        return (
            f"H: {drug} shows no association with a pre-specified negative "
            f"control outcome, supporting that the {outcome} association is not "
            f"driven by detection or confounding bias."
        )
    if design_type == "factorial_2x2_rct":
        return (
            f"H: The effect of {drug} on {outcome} is consistent across the "
            f"factorial strata, ruling out interaction-driven confounding."
        )
    if design_type == "n_of_1_crossover":
        return (
            f"H: Within-subject exposure to {drug} produces a measurable change "
            f"in surrogates of {outcome} at clinically achievable doses."
        )
    if design_type == "bariatric_natural_experiment":
        return (
            f"H: Exogenous assignment to {drug} via a policy/threshold discontinuity "
            f"yields {outcome} effects consistent with the RCT estimate."
        )
    if design_type == "bridging_ex_vivo":
        return (
            f"H: At human-achievable C_max, {drug} retains its ex vivo effect on "
            f"the {outcome}-relevant tissue, supporting dose translation."
        )
    return ""
