package widgets

import (
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"github.com/dweymouth/supersonic/ui/util"
)

// SearchEntry is a search entry widget that will issue a search command
// (aka call OnSearched) when a short span of time has elapsed since
// the user typed into the widget.
type SearchEntry struct {
	widget.Entry

	OnSearched func(string)
}

func NewSearchEntry() *SearchEntry {
	sf := &SearchEntry{}
	sf.ExtendBaseWidget(sf)
	sf.Init()
	return sf
}

// For use only by extending widgets
func (sf *SearchEntry) Init() {
	sf.PlaceHolder = "Search"
	sf.ActionItem = NewClearTextButton(func() {
		sf.SetText("")
	})
	debounceFunc := util.NewDebouncer(200*time.Millisecond, func() {
		sf.sendSearch(sf.Entry.Text)
	})
	sf.Entry.OnChanged = func(_ string) {
		if sf.updateActionButton() {
			sf.ActionItem.Refresh()
		}
		debounceFunc()
	}
}

func (s *SearchEntry) TypedKey(e *fyne.KeyEvent) {
	if e.Name == fyne.KeyEscape {
		s.SetText("")
		fyne.CurrentApp().Driver().CanvasForObject(s).Unfocus()
		return
	}
	s.Entry.TypedKey(e)
}

func (s *SearchEntry) Refresh() {
	s.updateActionButton()
	s.Entry.Refresh()
}

func (s *SearchEntry) MinSize() fyne.Size {
	return fyne.NewSize(200, s.Entry.MinSize().Height)
}

func (s *SearchEntry) updateActionButton() bool {
	btn := s.ActionItem.(*clearTextButton)
	oldResouce := btn.Resource
	if s.Text == "" {
		btn.Resource = theme.SearchIcon()
	} else {
		btn.Resource = theme.ContentClearIcon()
	}
	return oldResouce != btn.Resource
}

var _ fyne.Tappable = (*clearTextButton)(nil)

type clearTextButton struct {
	widget.Icon

	OnTapped func()
}

func (s *SearchEntry) sendSearch(text string) {
	if s.OnSearched != nil {
		s.OnSearched(text)
	}
}

func NewClearTextButton(onTapped func()) *clearTextButton {
	c := &clearTextButton{OnTapped: onTapped}
	c.ExtendBaseWidget(c)
	c.Resource = theme.SearchIcon()
	return c
}

func (c *clearTextButton) Tapped(*fyne.PointEvent) {
	if c.OnTapped != nil {
		c.OnTapped()
	}
}
