"""
Registry: BMI, Profil-Ziele (goal_weight, goal_bf_pct), body_progress_score.

Profilfelder sind unabhängig von der goals-Tabelle; operative Ziele über andere Keys.
"""

from placeholder_registry import (
    PlaceholderMetadata,
    MissingValuePolicy,
    EvidenceType,
    OutputType,
    PlaceholderType,
    register_placeholder,
)


def register_body_extras():
    bmi = PlaceholderMetadata(
        key="bmi",
        category="Körper",
        description="Body-Mass-Index aus letztem Gewicht und Profilgröße (cm)",
        resolver_module="backend/placeholder_resolver.py",
        resolver_function="calculate_bmi",
        data_layer_module="backend/data_layer/body_metrics.py",
        data_layer_function="get_bmi_data",
        source_tables=["profiles", "weight_log"],
        semantic_contract=(
            "BMI = Gewicht_kg / (Größe_m)² mit Größe_m = profiles.height / 100 "
            "und Gewicht = jüngster Eintrag in weight_log."
        ),
        business_meaning="Standard-Körpermaß für Coaching und Risiko-Kontext",
        unit="kg/m²",
        time_window="latest weight + aktuelle Profilgröße",
        output_type=OutputType.NUMERIC,
        placeholder_type=PlaceholderType.RAW_DATA,
        format_hint="Eine Dezimalstelle, ohne Einheit im String",
        example_output="24.3",
        minimum_data_requirements="Profil mit height > 0 und mindestens ein weight_log",
        quality_filter_policy=None,
        confidence_logic="high nur wenn BMI berechenbar; sonst insufficient / Anzeige nicht verfügbar",
        missing_value_policy=MissingValuePolicy(
            available=False,
            value_raw=None,
            missing_reason="no_data",
            legacy_display="nicht verfügbar",
        ),
        known_limitations=(
            "Keine ethnischen Referenzkurven; Profilgröße kann veraltet sein. "
            "Unterscheidet nicht Muskelmasse vs. Fett."
        ),
        layer_1_decision="body_metrics.get_bmi_data",
        layer_2a_decision="placeholder_resolver.calculate_bmi (Format)",
        layer_2b_reuse_possible=True,
        architecture_alignment="Phase 0c",
        issue_53_alignment="Layer 1 als Quelle",
        evidence={},
    )
    for field in (
        "key", "category", "description", "resolver_module", "resolver_function",
        "data_layer_module", "data_layer_function", "source_tables",
        "semantic_contract", "business_meaning", "unit", "time_window",
        "output_type", "placeholder_type", "format_hint", "example_output",
        "minimum_data_requirements", "confidence_logic", "missing_value_policy",
        "known_limitations", "layer_1_decision", "layer_2a_decision",
        "layer_2b_reuse_possible", "architecture_alignment", "issue_53_alignment",
    ):
        bmi.set_evidence(field, EvidenceType.CODE_DERIVED)
    bmi.set_evidence("business_meaning", EvidenceType.DRAFT_DERIVED)
    bmi.set_evidence("known_limitations", EvidenceType.MIXED)
    register_placeholder(bmi)

    gw = PlaceholderMetadata(
        key="goal_weight",
        category="Körper",
        description="Zielgewicht aus Profilfeld profiles.goal_weight (kg)",
        resolver_module="backend/placeholder_resolver.py",
        resolver_function="get_goal_weight",
        data_layer_module="backend/data_layer/body_metrics.py",
        data_layer_function="get_profile_goal_weight_data",
        source_tables=["profiles"],
        semantic_contract=(
            "Strategisches Soll-Gewicht im Profil; unabhängig von der goals-Tabelle "
            "(dort detaillierte Ziele mit Fortschritt)."
        ),
        business_meaning="Schneller Abgleich Prompt vs. Profil-Default-Zielgewicht",
        unit="kg",
        time_window="Profil-Snapshot",
        output_type=OutputType.NUMERIC,
        placeholder_type=PlaceholderType.RAW_DATA,
        format_hint="Eine Dezimalstelle oder Text „nicht gesetzt“",
        example_output="82.0",
        minimum_data_requirements="profiles.goal_weight IS NOT NULL",
        quality_filter_policy=None,
        confidence_logic="high wenn gesetzt",
        missing_value_policy=MissingValuePolicy(
            available=False,
            value_raw=None,
            missing_reason="not_set",
            legacy_display="nicht gesetzt",
        ),
        known_limitations="Kann von aktiven goals.weight-Zielen abweichen.",
        layer_1_decision="body_metrics.get_profile_goal_weight_data",
        layer_2a_decision="placeholder_resolver.get_goal_weight",
        layer_2b_reuse_possible=True,
        architecture_alignment="Phase 0c",
        issue_53_alignment="Layer 1 als Quelle",
        evidence={},
    )
    for field in (
        "key", "category", "description", "resolver_module", "resolver_function",
        "data_layer_module", "data_layer_function", "source_tables",
        "semantic_contract", "unit", "time_window", "output_type",
        "placeholder_type", "format_hint", "example_output",
        "minimum_data_requirements", "confidence_logic", "missing_value_policy",
        "layer_1_decision", "layer_2a_decision", "layer_2b_reuse_possible",
        "architecture_alignment", "issue_53_alignment",
    ):
        gw.set_evidence(field, EvidenceType.CODE_DERIVED)
    gw.set_evidence("business_meaning", EvidenceType.DRAFT_DERIVED)
    gw.set_evidence("known_limitations", EvidenceType.MIXED)
    register_placeholder(gw)

    gbf = PlaceholderMetadata(
        key="goal_bf_pct",
        category="Körper",
        description="Ziel-Körperfettanteil aus Profilfeld profiles.goal_bf_pct (%)",
        resolver_module="backend/placeholder_resolver.py",
        resolver_function="get_goal_bf_pct",
        data_layer_module="backend/data_layer/body_metrics.py",
        data_layer_function="get_profile_goal_bf_pct_data",
        source_tables=["profiles"],
        semantic_contract="Strategisches Ziel-KFA im Profil.",
        business_meaning="Prompt-Abgleich mit Profil-Ziel-KFA",
        unit="%",
        time_window="Profil-Snapshot",
        output_type=OutputType.NUMERIC,
        placeholder_type=PlaceholderType.RAW_DATA,
        format_hint="Eine Dezimalstelle oder Text „nicht gesetzt“",
        example_output="15.0",
        minimum_data_requirements="profiles.goal_bf_pct IS NOT NULL",
        quality_filter_policy=None,
        confidence_logic="high wenn gesetzt",
        missing_value_policy=MissingValuePolicy(
            available=False,
            value_raw=None,
            missing_reason="not_set",
            legacy_display="nicht gesetzt",
        ),
        known_limitations="Kann von goals body_fat abweichen.",
        layer_1_decision="body_metrics.get_profile_goal_bf_pct_data",
        layer_2a_decision="placeholder_resolver.get_goal_bf_pct",
        layer_2b_reuse_possible=True,
        architecture_alignment="Phase 0c",
        issue_53_alignment="Layer 1 als Quelle",
        evidence={},
    )
    for field in (
        "key", "category", "description", "resolver_module", "resolver_function",
        "data_layer_module", "data_layer_function", "source_tables",
        "semantic_contract", "unit", "time_window", "output_type",
        "placeholder_type", "format_hint", "example_output",
        "minimum_data_requirements", "confidence_logic", "missing_value_policy",
        "layer_1_decision", "layer_2a_decision", "layer_2b_reuse_possible",
        "architecture_alignment", "issue_53_alignment",
    ):
        gbf.set_evidence(field, EvidenceType.CODE_DERIVED)
    gbf.set_evidence("business_meaning", EvidenceType.DRAFT_DERIVED)
    gbf.set_evidence("known_limitations", EvidenceType.MIXED)
    register_placeholder(gbf)

    bps = PlaceholderMetadata(
        key="body_progress_score",
        category="Körper",
        description="Körper-Fortschritts-Score 0–100, gewichtet nach Focus (Abnehmen, Muskelaufbau, Recomp)",
        resolver_module="backend/placeholder_resolver.py",
        resolver_function="_safe_int",
        data_layer_module="backend/data_layer/body_metrics.py",
        data_layer_function="calculate_body_progress_score",
        source_tables=[
            "user_focus_area_weights",
            "focus_area_definitions",
            "goals",
            "weight_log",
            "caliper_log",
            "circumference_log",
        ],
        semantic_contract=(
            "Gewichteter Mittelwert aus bis zu drei Komponenten: Trend vs. Gewichtsziel, "
            "Körperzusammensetzung (FM/LBM/Recomp-Quadrant), Taille-Trend. "
            "Komponenten nur aktiv, wenn passende Focus-Gewichte > 0."
        ),
        business_meaning="Meta-KPI: passt dokumentierter Körperfortschritt zur gewichteten Körper-Priorität?",
        unit="Score (0–100)",
        time_window="composite (u. a. 28d Deltas, Ziel-Fortschritt)",
        output_type=OutputType.NUMERIC,
        placeholder_type=PlaceholderType.SCORE,
        format_hint="Ganzzahl oder „nicht verfügbar“",
        example_output="72",
        minimum_data_requirements=(
            "Summe der Körper-Focus-Gewichte (weight_loss + muscle_gain + body_recomposition) > 0 "
            "und mindestens eine bewertbare Komponente mit Daten."
        ),
        quality_filter_policy=None,
        confidence_logic="Kein separates Confidence-Feld; None wenn keine Körper-Gewichtung oder keine Teilscores.",
        missing_value_policy=MissingValuePolicy(
            available=False,
            value_raw=None,
            missing_reason="not_applicable",
            legacy_display="nicht verfügbar",
        ),
        known_limitations=(
            "Abhängig von user_focus_area_weights und aktiven weight-goals für Gewichts-Teilscore. "
            "Taille-Score wird mit festem Basisgewicht 20+ eingemischt und kann dominieren."
        ),
        layer_1_decision="body_metrics.calculate_body_progress_score",
        layer_2a_decision="placeholder_resolver._safe_int('body_progress_score', …)",
        layer_2b_reuse_possible=True,
        architecture_alignment="Phase 0c",
        issue_53_alignment="Layer 1 als Quelle",
        evidence={},
    )
    for field in (
        "key", "category", "description", "resolver_module", "resolver_function",
        "data_layer_module", "data_layer_function", "source_tables",
        "semantic_contract", "unit", "time_window", "output_type",
        "placeholder_type", "format_hint", "example_output",
        "minimum_data_requirements", "confidence_logic", "missing_value_policy",
        "layer_1_decision", "layer_2a_decision", "layer_2b_reuse_possible",
        "architecture_alignment", "issue_53_alignment",
    ):
        bps.set_evidence(field, EvidenceType.CODE_DERIVED)
    bps.set_evidence("business_meaning", EvidenceType.DRAFT_DERIVED)
    bps.set_evidence("known_limitations", EvidenceType.MIXED)
    register_placeholder(bps)


register_body_extras()
