"""Cursor value callbacks.

Handles:
- Cursor update button -> recompute interpolated values
- Cursor values table rendering
"""

from __future__ import annotations

from typing import Any

import dash
from dash import Input, Output, State, html
from dash.exceptions import PreventUpdate

from impakt.web.callbacks.plot_callbacks import _resolve_channels
from impakt.web.components.cursors import build_cursor_values_table
from impakt.web.state import AppState


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

    @app.callback(
        Output("cursor-values-table", "children"),
        [Input("cursor-update-btn", "n_clicks")],
        [
            State("selected-channels-store", "data"),
            State("cfc-select", "value"),
            State("y-align-check", "value"),
            State("x-align-method", "value"),
            State("x-align-value", "value"),
            State("show-resultant", "value"),
            State("cursor-x1", "value"),
            State("cursor-x2", "value"),
        ],
    )
    def update_cursor_table(
        n_clicks: int | None,
        selected_keys: list[str] | None,
        cfc_value: str,
        y_align: bool,
        x_align_method: str,
        x_align_value: float | None,
        show_resultant: bool,
        cursor_x1: float | None,
        cursor_x2: float | None,
    ) -> Any:
        if not n_clicks:
            return html.Div("Select channels and click 'Update'", className="text-muted small")

        if cursor_x1 is None or cursor_x2 is None:
            return html.Div("Set both cursor positions", className="text-muted small")

        if not selected_keys:
            return html.Div("No channels selected", className="text-muted small")

        channels = _resolve_channels(
            selected_keys,
            app_state,
            cfc_value,
            y_align,
            x_align_method or "none",
            x_align_value,
            show_resultant,
        )

        return build_cursor_values_table(channels, cursor_x1, cursor_x2)
