"""Option row widget for displaying a single configuration option."""

from textual.app import ComposeResult
from textual.containers import Horizontal
from textual.message import Message
from textual.widget import Widget
from textual.widgets import Button, Label, Static

from ..models import OptionModel, OptionType


class OptionChanged(Message):
    """Message emitted when an option value changes."""

    def __init__(self, option_name: str, old_value: str | None, new_value: str | None) -> None:
        self.option_name = option_name
        self.old_value = old_value
        self.new_value = new_value
        super().__init__()


class OptionRow(Widget):
    """Container widget for a single configuration option."""

    DEFAULT_CSS = """
    OptionRow {
        layout: horizontal;
        height: auto;
        min-height: 3;
        padding: 1;
        margin-bottom: 1;
        background: $surface;
        border: solid $surface-lighten-2;
    }

    OptionRow:focus-within {
        border: solid $primary;
    }

    OptionRow.modified {
        border-left: wide $warning;
    }

    OptionRow .option-label {
        width: 30;
        padding-right: 2;
    }

    OptionRow .option-value {
        width: 1fr;
    }

    OptionRow .option-help {
        width: auto;
        padding-left: 1;
    }

    OptionRow .type-badge {
        width: auto;
        padding: 0 1;
        background: $primary-darken-2;
    }
    """

    def __init__(self, model: OptionModel, **kwargs) -> None:
        """Initialize option row.

        Args:
            model: The option model containing definition and current value
        """
        super().__init__(**kwargs)
        self.model = model
        self._original_value = model.current.value

    def compose(self) -> ComposeResult:
        """Compose the option row layout."""
        with Horizontal():
            # Option name label
            yield Label(
                self.model.definition.name,
                classes="option-label"
            )

            # Type badge
            yield Static(
                self.model.definition.option_type.value,
                classes="type-badge"
            )

            # Value display/widget
            yield Static(
                self.model.display_value or "(empty)",
                classes="option-value",
                id=f"value-{self.model.definition.name}"
            )

            # Help button
            yield Button("?", variant="default", classes="option-help")

    def on_mount(self) -> None:
        """Set up initial state."""
        self._update_modified_class()

    def _update_modified_class(self) -> None:
        """Update the modified class based on current state."""
        if self.model.is_modified or not self.model.is_default:
            self.add_class("modified")
        else:
            self.remove_class("modified")

    def get_value(self) -> str | None:
        """Get the current value."""
        return self.model.current.value

    def set_value(self, value: str | None) -> None:
        """Set a new value and emit change message."""
        old_value = self.model.current.value
        if old_value != value:
            self.model.current.value = value
            self.model.current.is_modified = True
            self._update_modified_class()

            # Update display
            value_widget = self.query_one(f"#value-{self.model.definition.name}", Static)
            value_widget.update(value or "(empty)")

            # Emit change message
            self.post_message(OptionChanged(
                option_name=self.model.definition.name,
                old_value=old_value,
                new_value=value
            ))

    def reset_to_default(self) -> None:
        """Reset the option to its default value."""
        self.set_value(self.model.definition.default_value)
        self.model.current.is_modified = False
        self._update_modified_class()

    def on_button_pressed(self, event: Button.Pressed) -> None:
        """Handle help button press."""
        # Show option help in notification
        desc = self.model.definition.description or "No description available."
        # Truncate long descriptions
        if len(desc) > 200:
            desc = desc[:200] + "..."

        self.notify(
            f"[bold]{self.model.definition.name}[/bold]\n\n{desc}",
            title="Option Help",
            timeout=10
        )
