package tui

import (
	_ "embed"
	"fmt"
	"strings"

	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

var (
	//go:embed help-pages/hotkeys.txt
	hotkeysHelpText string

	//go:embed help-pages/searching.txt
	searchingHelpText string
)

type HelpPage struct {
	*tview.Box
	pages       []*tview.TextView
	currentPage int

	filters     []string
	filterHints map[string]string
}

func NewHelpPage(filters []string, hints map[string]string) *HelpPage {
	hp := &HelpPage{
		Box:         tview.NewBox(),
		filters:     filters,
		filterHints: hints,
	}

	page := tview.NewTextView().
		SetDynamicColors(true).
		SetText(hotkeysHelpText)
	hp.addPage(page)

	page = tview.NewTextView().
		SetDynamicColors(true).
		SetText(fmt.Sprintf(searchingHelpText, hp.getFiltersText()))
	hp.addPage(page)

	return hp
}

func (hp *HelpPage) addPage(page *tview.TextView) {
	hp.pages = append(hp.pages, page)
}

func (hp *HelpPage) getFiltersText() string {
	if len(hp.filters) == 0 {
		return "\t\tNo filters defined.\n"
	}

	filtersText := strings.Builder{}
	gapSize := 4

	tagMaxWidth := 3
	for _, filter := range hp.filters {
		tagMaxWidth = max(tagMaxWidth, len(filter))
	}
	filtersText.WriteString("\t\t[yellow::b]Tag")
	filtersText.WriteString(strings.Repeat(" ", gapSize))
	filtersText.WriteString("\tValue[-::-]\n\n")

	for _, filter := range hp.filters {
		filtersText.WriteString("\t\t")
		filtersText.WriteString(filter)
		filtersText.WriteString(strings.Repeat(" ", tagMaxWidth-len(filter)+gapSize))
		filtersText.WriteString(hp.filterHints[filter])
		filtersText.WriteRune('\n')
	}

	return filtersText.String()
}

func (hp *HelpPage) Draw(screen tcell.Screen) {
	x, y, width, height := hp.GetInnerRect()
	hp.pages[hp.currentPage].SetRect(x+1, y+1, width-2, height-2)
	hp.pages[hp.currentPage].Draw(screen)
}

func (hp *HelpPage) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
	return hp.WrapInputHandler(func(event *tcell.EventKey, _ func(tview.Primitive)) {
		if event.Key() == tcell.KeyEnter {
			hp.currentPage++
			hp.currentPage %= len(hp.pages)
			return
		}
		hp.pages[hp.currentPage].InputHandler()(event, func(tview.Primitive) {})
	})
}

func (hp *HelpPage) MouseHandler() func(action tview.MouseAction, event *tcell.EventMouse, setFocus func(p tview.Primitive)) (consumed bool, capture tview.Primitive) {
	return hp.WrapMouseHandler(func(action tview.MouseAction, event *tcell.EventMouse, _ func(tview.Primitive)) (consumed bool, capture tview.Primitive) {
		return hp.pages[hp.currentPage].MouseHandler()(action, event, func(tview.Primitive) {})
	})
}