package screens

import (
	"testing"

	tea "charm.land/bubbletea/v2"

	"git.secluded.site/keld/internal/ui"
)

func TestOverwriteTitle(t *testing.T) {
	t.Parallel()

	o := NewOverwrite(testStyles())
	if got := o.Title(); got != "Overwrite existing files?" {
		t.Errorf("Title() = %q, want %q", got, "Overwrite existing files?")
	}
}

func TestOverwriteSelectionEmpty(t *testing.T) {
	t.Parallel()

	o := NewOverwrite(testStyles())
	if got := o.Selection(); got != "" {
		t.Errorf("Selection() before interaction = %q, want empty", got)
	}
}

func TestOverwriteKeyBindings(t *testing.T) {
	t.Parallel()

	o := NewOverwrite(testStyles())
	bindings := o.KeyBindings()

	if len(bindings) == 0 {
		t.Fatal("KeyBindings() returned no bindings")
	}
}

func TestOverwriteEscReturnsBack(t *testing.T) {
	t.Parallel()

	o := NewOverwrite(testStyles())
	o.Init()
	o.Update(tea.WindowSizeMsg{Width: 80, Height: 20})

	_, cmd := o.Update(tea.KeyPressMsg{Code: tea.KeyEscape})

	if cmd == nil {
		t.Fatal("expected BackCmd on Esc")
	}
	msg := cmd()
	if _, ok := msg.(ui.BackMsg); !ok {
		t.Errorf("cmd produced %T, want ui.BackMsg", msg)
	}
}

func TestOverwriteCompleteReturnsDone(t *testing.T) {
	t.Parallel()

	o := NewOverwrite(testStyles())
	o.Init()
	o.Update(tea.WindowSizeMsg{Width: 80, Height: 20})

	// Default selection is the first option (if-changed). Press enter.
	var screen ui.Screen
	var cmd tea.Cmd
	screen, cmd = o.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
	_, cmd = drain(screen.(*Overwrite), cmd)

	if cmd == nil {
		t.Fatal("expected DoneCmd after form completion")
	}
	msg := cmd()
	if _, ok := msg.(ui.DoneMsg); !ok {
		t.Errorf("cmd produced %T, want ui.DoneMsg", msg)
	}
}

func TestOverwriteDefaultIsIfChanged(t *testing.T) {
	t.Parallel()

	o := NewOverwrite(testStyles())
	o.Init()
	o.Update(tea.WindowSizeMsg{Width: 80, Height: 20})

	// Press enter on the default selection.
	var screen ui.Screen
	var cmd tea.Cmd
	screen, cmd = o.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
	o, _ = drain(screen.(*Overwrite), cmd)

	if got := o.Value(); got != "if-changed" {
		t.Errorf("Value() = %q, want %q (default should be if-changed)", got, "if-changed")
	}
}

func TestOverwriteSelectionShowsValue(t *testing.T) {
	t.Parallel()

	o := NewOverwrite(testStyles())
	o.Init()
	o.Update(tea.WindowSizeMsg{Width: 80, Height: 20})

	// Press enter on the default.
	var screen ui.Screen
	var cmd tea.Cmd
	screen, cmd = o.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
	o, _ = drain(screen.(*Overwrite), cmd)

	if got := o.Selection(); got != "if-changed" {
		t.Errorf("Selection() = %q, want %q", got, "if-changed")
	}
}

func TestOverwriteReinitAfterBack(t *testing.T) {
	t.Parallel()

	o := NewOverwrite(testStyles())
	o.Init()
	o.Update(tea.WindowSizeMsg{Width: 80, Height: 20})

	// Complete the form.
	var screen ui.Screen
	var cmd tea.Cmd
	screen, cmd = o.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
	o, _ = drain(screen.(*Overwrite), cmd)

	// Re-init (simulates back navigation).
	o.Init()
	o.Update(tea.WindowSizeMsg{Width: 80, Height: 20})

	// Should be functional again.
	screen, cmd = o.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
	_, cmd = drain(screen.(*Overwrite), cmd)

	if cmd == nil {
		t.Fatal("expected DoneCmd after re-init")
	}
	msg := cmd()
	if _, ok := msg.(ui.DoneMsg); !ok {
		t.Errorf("after re-init, cmd produced %T, want ui.DoneMsg", msg)
	}
}
