"""
Comprehensive binding tests for all bindable FastHTML components.

This test suite covers:
- Input (text) - already tested
- Checkbox - already tested
- Textarea
- Select (single)
- Select (multiple)
- Range (slider)
- Radio buttons
- Button
- Input with Datalist (combobox)
"""

from dataclasses import dataclass

from fasthtml.components import (
  Input, Label, Option, Datalist
)

from myfasthtml.controls.helpers import mk
from myfasthtml.core.bindings import Binding


@dataclass
class Data:
  value: str = "hello world"


@dataclass
class NumericData:
  value: int = 50


@dataclass
class BoolData:
  value: bool = True


@dataclass
class ListData:
  value: list = None
  
  def __post_init__(self):
    if self.value is None:
      self.value = []


class TestBindingDatalist:
  """Tests for binding Input with Datalist (combobox)."""
  
  def test_i_can_bind_input_with_datalist(self, user, rt):
    """
    Input with datalist should allow both free text and suggestions.
    """
    
    @rt("/")
    def index():
      data = Data("")
      datalist = Datalist(
        Option(value="suggestion1"),
        Option(value="suggestion2"),
        Option(value="suggestion3"),
        id="suggestions"
      )
      input_elt = Input(
        name="input_name",
        list="suggestions"
      )
      label_elt = Label()
      
      mk.manage_binding(input_elt, Binding(data))
      mk.manage_binding(label_elt, Binding(data))
      
      return input_elt, datalist, label_elt
    
    user.open("/")
    user.should_see("")
    
    testable_input = user.find_element("input[list='suggestions']")
    
    # Can type free text
    testable_input.send("custom value")
    user.should_see("custom value")
    
    # Can select from suggestions
    testable_input.select_suggestion("suggestion2")
    user.should_see("suggestion2")
  
  def test_datalist_suggestions_are_available(self, user, rt):
    """
    Datalist suggestions should be accessible for validation.
    """
    
    @rt("/")
    def index():
      data = Data("")
      datalist = Datalist(
        Option(value="apple"),
        Option(value="banana"),
        Option(value="cherry"),
        id="fruits"
      )
      input_elt = Input(
        name="input_name",
        list="fruits"
      )
      label_elt = Label()
      
      mk.manage_binding(input_elt, Binding(data))
      mk.manage_binding(label_elt, Binding(data))
      
      return input_elt, datalist, label_elt
    
    user.open("/")
    
    testable_input = user.find_element("input[list='fruits']")
    
    # Check that suggestions are available
    suggestions = testable_input.suggestions
    assert "apple" in suggestions
    assert "banana" in suggestions
    assert "cherry" in suggestions
