"""Criteria computation callbacks.

Uses Session.compute_criteria() and Session.evaluate() from the
scripting API — the same path used by programmatic scripts.
"""

from __future__ import annotations

from typing import Any

import dash
from dash import Input, Output, State, html

from impakt.web.components.criteria import build_criteria_results_display
from impakt.web.state import AppState


def register_criteria_callbacks(app: dash.Dash, app_state: AppState) -> None:
    """Register criteria-related callbacks."""

    @app.callback(
        Output("criteria-results", "children"),
        [Input("compute-criteria-btn", "n_clicks")],
        [State("protocol-select", "value")],
    )
    def compute_criteria(n_clicks: int | None, protocol: str) -> Any:
        if not n_clicks:
            return html.Div(
                "Click 'Compute All' to auto-detect channels and calculate injury criteria.",
                className="text-muted small",
            )

        primary = app_state.primary_test
        if primary is None:
            return html.Div("No test loaded.", className="text-danger small")

        # Use Session.compute_criteria() — single code path for script + web
        criteria = primary.compute_criteria()

        if not criteria:
            return html.Div(
                "No criteria could be computed. Check that the test has the required channels "
                "(head acceleration, neck force/moment, chest deflection, femur load).",
                className="text-warning small",
            )

        # Score against protocol — use Session.evaluate()
        try:
            protocol_result = primary.evaluate(protocol)
        except Exception:
            protocol_result = None

        return build_criteria_results_display(criteria, protocol_result)
