"""Editable parameter rows per controller group."""
from textual.app import ComposeResult
from textual.containers import Vertical, Horizontal
from textual.widgets import Static, Input, Button

from ..protocol import ParamDef, PARAMS, build_param_write


class ParamRow(Horizontal):
    """Single parameter row with label, current value, input, and send button."""

    DEFAULT_CSS = """
    ParamRow {
        height: auto;
        width: 100%;
        padding: 0;
        margin: 0;
    }
    ParamRow .param-label {
        width: 16;
        height: 1;
        padding: 0 1;
    }
    ParamRow .param-value {
        width: 14;
        height: 1;
        padding: 0 1;
        color: $success;
    }
    ParamRow Input {
        width: 1fr;
    }
    ParamRow Button {
        width: 6;
        min-width: 6;
    }
    """

    def __init__(self, param: ParamDef, send_callback):
        super().__init__()
        self.param = param
        self._send_callback = send_callback

    def compose(self) -> ComposeResult:
        yield Static(self.param.name, classes="param-label")
        yield Static("---", id=f"val_{self.param.id:02x}", classes="param-value")
        yield Input(placeholder="new", id=f"input_{self.param.id:02x}")
        yield Button("Go", id=f"btn_{self.param.id:02x}", variant="primary")

    def set_current_value(self, value: float):
        fmt = self.param.fmt
        label = self.query_one(f"#val_{self.param.id:02x}", Static)
        label.update(f"{value:{fmt}}")

    def on_button_pressed(self, event: Button.Pressed) -> None:
        inp = self.query_one(Input)
        try:
            value = float(inp.value)
        except ValueError:
            return
        frame = build_param_write(self.param.id, self.param.ptype, value)
        self._send_callback(frame)
        inp.value = ""

    def on_input_submitted(self, event: Input.Submitted) -> None:
        try:
            value = float(event.value)
        except ValueError:
            return
        frame = build_param_write(self.param.id, self.param.ptype, value)
        self._send_callback(frame)
        event.input.value = ""


class ParamGroup(Vertical):
    """A group of parameter rows for one controller."""

    DEFAULT_CSS = """
    ParamGroup {
        width: 100%;
        height: auto;
        padding: 0 1;
        margin: 0 0 1 0;
    }
    """

    def __init__(self, group_name: str, send_callback):
        super().__init__()
        self.group_name = group_name
        self._send_callback = send_callback
        self._params = [p for p in PARAMS if p.group == group_name]

    def compose(self) -> ComposeResult:
        yield Static(f"[bold]{self.group_name} CONTROLLER[/bold]")
        for p in self._params:
            yield ParamRow(p, self._send_callback)

    def update_param(self, param_id: int, value: float):
        for row in self.query(ParamRow):
            if row.param.id == param_id:
                row.set_current_value(value)
                return
