package ui

import (
	"testing"

	tea "github.com/charmbracelet/bubbletea"

	"github.com/gmgauthier/gostations/internal/radio"
)

func TestApp_BasicKeyHandling(t *testing.T) {
	app := NewApp([]radio.Station{
		{Name: "Test1", Url: "http://a", Codec: "MP3", Bitrate: "128"},
	})

	// Send q
	model, cmd := app.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'q'}})
	if !model.(*App).quitting {
		t.Error("q did not set quitting")
	}
	_ = cmd

	// Send window size
	model, _ = app.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
	a := model.(*App)
	if a.list.Width() == 0 {
		t.Log("list size not updated (may be ok in test)")
	}
}

func TestApp_AutoFilterOnTyping(t *testing.T) {
	app := NewApp([]radio.Station{
		{Name: "WFMT 98.7", Url: "http://wfmt", Codec: "MP3", Bitrate: "128", Tags: "chicago,classical"},
		{Name: "Other Station", Url: "http://other", Codec: "AAC", Bitrate: "64", Tags: "news"},
	})

	// Simulate typing 'W' (auto enter filter). Drive any returned cmds.
	model, cmd := app.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'W'}})
	a := model.(*App)
	for cmd != nil {
		msg := cmd()
		if msg == nil {
			break
		}
		model, cmd = a.Update(msg.(tea.Msg))
		a = model.(*App)
	}

	fv := a.list.FilterValue()
	if fv != "W" {
		t.Errorf("expected filter value 'W' after typing W, got %q", fv)
	}
	visible := a.list.VisibleItems()
	if len(visible) == 0 {
		t.Error("expected some visible items after filter 'W'")
	}

	// Now type the rest of "WFMT", driving cmds each time
	for _, r := range "FMT" {
		model, cmd = a.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{r}})
		a = model.(*App)
		for cmd != nil {
			msg := cmd()
			if msg == nil {
				break
			}
			model, cmd = a.Update(msg.(tea.Msg))
			a = model.(*App)
		}
	}

	fv = a.list.FilterValue()
	if fv != "WFMT" {
		t.Errorf("expected filter value 'WFMT', got %q", fv)
	}

	// Note: in live typing simulation, state may stay 'filtering' and filteredItems update may depend on internal cmd processing.
	// For verifying the custom substring filter logic itself, use SetFilterText which synchronously applies.
	a.list.SetFilterText("WFMT")

	visible = a.list.VisibleItems()
	if len(visible) != 1 {
		t.Errorf("expected exactly 1 item for 'WFMT' substring filter, got %d", len(visible))
	}
	if len(visible) > 0 {
		if it, ok := visible[0].(item); ok {
			if it.station.Name != "WFMT 98.7" {
				t.Errorf("expected 'WFMT 98.7' to be the match, got %q", it.station.Name)
			}
		}
	}
}
