package main

import (
	"fmt"
    "io"
	"strings"

	"github.com/charmbracelet/bubbles/textinput"
	tea "github.com/charmbracelet/bubbletea"
    "github.com/charmbracelet/lipgloss"
    "github.com/charmbracelet/bubbles/list"
)


type item string
func (i item) FilterValue() string { return "" }
type itemDelegate struct{}

func (d itemDelegate) Height() int                             { return 1 }
func (d itemDelegate) Spacing() int                            { return 0 }
func (d itemDelegate) Update(_ tea.Msg, _ *list.Model) tea.Cmd { return nil }
func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
	i, ok := listItem.(item)
	if !ok {
		return
	}

	str := fmt.Sprintf("%d. %s", index+1, i)

	fn := lipgloss.NewStyle().PaddingLeft(2).Render
	if index == m.Index() {
		fn = func(s ...string) string {
			return lipgloss.NewStyle().PaddingLeft(0).PaddingRight(1).Background(lipgloss.Color("#0F7FCF")).Render("> " + strings.Join(s, " "))
		}
	}

	fmt.Fprint(w, fn(str))
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	var cmd tea.Cmd

	switch msg := msg.(type) {
    case tea.KeyMsg:
        switch msg.Type {
        case tea.KeyCtrlC, tea.KeyEsc:
            m.quitting = true;
            return m, tea.Quit
        case tea.KeyEnter:
            i, ok := m.list.SelectedItem().(item)
            if ok {
                m.choice = string(i)
            }
            return m, tea.Quit
        case tea.KeyUp, tea.KeyCtrlK:
            m.list.CursorUp()
        case tea.KeyDown, tea.KeyCtrlJ:
            m.list.CursorDown()
        }

    // We handle errors just like any other message
    case errMsg:
        m.err = msg
        return m, nil

    case tea.WindowSizeMsg:
        m.textInput.Width = msg.Width
        m.list.SetWidth(msg.Width)
        return m, nil
    }
	m.textInput, cmd = m.textInput.Update(msg)
	return m, cmd
}

func (m model) View() string {
	if m.choice != "" {
		return  m.choice
	}
	if m.quitting {
		return ""
	}
	return fmt.Sprintf("%s\n%s\n",
		m.textInput.View(),
        m.list.View(),
	)
}


type (
	errMsg error
)

type model struct {
	textInput textinput.Model
	list     list.Model
	choice   string
	quitting bool
	err       error
}

func initialModel(items []list.Item) model {
	const defaultWidth = 20

	l := list.New(items, itemDelegate{}, defaultWidth, 14)
	l.SetShowStatusBar(false)
	l.SetFilteringEnabled(false)
    l.SetShowHelp(false)
    l.SetShowTitle(false)
    l.SetShowPagination(false)
	ti := textinput.New()
	ti.Focus()
	ti.CharLimit = 156
	ti.Width = 20

	return model{
		textInput: ti,
        list:     l,
		err:       nil,
	}
}

func (m model) Init() tea.Cmd {
	return textinput.Blink
}