package tui

import (
	"slices"
	"strings"

	"charm.land/lipgloss/v2"
	"github.com/charmbracelet/x/ansi"
)

// Effort choices come from the active model, not the command catalog's examples.
func (m *ChatModel) openEffortSelector(levels []string) {
	m.effortOptions = slices.Clone(levels)
	m.effortSelected = max(0, slices.Index(levels, m.Effort))
	m.TextArea.Reset()
	m.syncLayout()
}

func (m ChatModel) effortSelectorView() string {
	if len(m.effortOptions) == 0 {
		return ""
	}
	width := m.chatWidth()
	selected := m.effortSelected
	// Keep the selected tier visible when the terminal cannot fit every tier.
	left, right := 0, len(m.effortOptions)
	label := func(i int) string {
		if i == selected {
			return " [" + m.effortOptions[i] + "] "
		}
		return m.effortOptions[i]
	}
	plain := func() string {
		parts := make([]string, 0, right-left)
		for i := left; i < right; i++ {
			parts = append(parts, label(i))
		}
		line := strings.Join(parts, " ─ ")
		if left > 0 {
			line = "‹ " + line
		}
		if right < len(m.effortOptions) {
			line += " ›"
		}
		return line
	}
	for ansi.StringWidth(plain()) > width && right-left > 1 {
		if selected-left > right-1-selected {
			left++
		} else {
			right--
		}
	}
	parts := make([]string, 0, right-left)
	for i := left; i < right; i++ {
		style := m.effortTierStyle(m.effortOptions[i])
		if i == selected {
			style = style.Inherit(m.Styles.Selected).Bold(true)
		}
		parts = append(parts, style.Render(label(i)))
	}
	decor := m.Styles.Decor.Render
	prefix, suffix := "", ""
	if left > 0 {
		prefix = decor("‹ ")
	}
	if right < len(m.effortOptions) {
		suffix = decor(" ›")
	}
	return ansi.Truncate(prefix+strings.Join(parts, decor(" ─ "))+suffix, width, "")
}

func (m ChatModel) effortTierStyle(level string) lipgloss.Style {
	switch level {
	case "low":
		return m.Styles.EffortLow
	case "medium":
		return m.Styles.EffortMedium
	case "high":
		return m.Styles.EffortHigh
	case "xhigh":
		return m.Styles.EffortXHigh
	case "max":
		return m.Styles.EffortMax
	default:
		return m.Styles.Muted
	}
}
