"""Channel selection and filtering callbacks.

Handles:
- DataTable row selection -> updates selected channels store
- Wildcard filter + facet dropdowns -> filters table rows
- Selected channels badge display
- Filter clear button
"""

from __future__ import annotations

from typing import Any

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

from impakt.web.components.channel_grid import (
    build_selected_channels_badges,
    filter_rows,
)
from impakt.web.state import AppState


def register_channel_callbacks(app: dash.Dash, app_state: AppState) -> None:
    """Register all channel selection and filtering callbacks."""

    @app.callback(
        Output("selected-channels-store", "data"),
        [Input("channel-grid", "selected_rows")],
        [State("channel-grid", "data")],
    )
    def sync_selection_to_store(
        selected_row_indices: list[int] | None,
        current_data: list[dict[str, Any]] | None,
    ) -> list[str]:
        """When user checks/unchecks rows in the DataTable, update the store."""
        if not selected_row_indices or not current_data:
            return []

        keys = []
        for idx in selected_row_indices:
            if 0 <= idx < len(current_data):
                keys.append(current_data[idx]["key"])
        return keys

    @app.callback(
        Output("selected-channels-badges", "children"),
        [Input("selected-channels-store", "data")],
    )
    def update_badges(selected_keys: list[str] | None) -> list:
        return build_selected_channels_badges(selected_keys or [], app_state)

    @app.callback(
        Output("channel-grid", "data"),
        [
            Input("channel-filter-input", "value"),
            Input("channel-filter-clear", "n_clicks"),
            Input("facet-body", "value"),
            Input("facet-meas", "value"),
            Input("facet-direction", "value"),
        ],
        [State("channel-grid-all-rows", "data")],
    )
    def apply_filters(
        pattern: str | None,
        clear_clicks: int | None,
        body: str | None,
        meas: str | None,
        direction: str | None,
        all_rows: list[dict[str, Any]] | None,
    ) -> list[dict[str, Any]]:
        """Filter the channel grid based on wildcard pattern and facets."""
        if not all_rows:
            return []

        # If clear was clicked, return all rows
        trigger = dash.ctx.triggered_id
        if trigger == "channel-filter-clear":
            return all_rows

        return filter_rows(
            all_rows,
            pattern=pattern or "",
            body=body or "",
            meas=meas or "",
            direction=direction or "",
        )

    @app.callback(
        [
            Output("channel-filter-input", "value"),
            Output("facet-body", "value"),
            Output("facet-meas", "value"),
            Output("facet-direction", "value"),
        ],
        [Input("channel-filter-clear", "n_clicks")],
        prevent_initial_call=True,
    )
    def clear_filters(n_clicks: int | None) -> tuple[str, str, str, str]:
        """Clear all filter inputs."""
        return "", "", "", ""
