package theme

import (
	"image/color"
	"testing"
)

func TestNewDark(t *testing.T) {
	s := New(true)

	if !s.Dark {
		t.Error("New(true).Dark = false, want true")
	}
}

func TestNewLight(t *testing.T) {
	s := New(false)

	if s.Dark {
		t.Error("New(false).Dark = true, want false")
	}
}

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

	for _, isDark := range []bool{true, false} {
		name := "dark"
		if !isDark {
			name = "light"
		}

		t.Run(name, func(t *testing.T) {
			t.Parallel()

			s := New(isDark)
			colours := map[string]color.Color{
				"Accent":    s.Accent,
				"Secondary": s.Secondary,
				"Warning":   s.Warning,
				"Confirm":   s.Confirm,
			}
			for label, c := range colours {
				if c == nil {
					t.Errorf("%s is nil", label)
				}
			}
		})
	}
}

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

	for _, isDark := range []bool{true, false} {
		name := "dark"
		if !isDark {
			name = "light"
		}
		t.Run(name, func(t *testing.T) {
			t.Parallel()

			s := New(isDark)
			// The ThemeFunc is called with an arbitrary bool; it
			// should always use the isDark captured at build time.
			styles := s.Huh.Theme(isDark)
			if styles == nil {
				t.Fatal("Theme() returned nil Styles")
			}
		})
	}
}

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

	// Build a dark theme, then call the ThemeFunc with isDark=false.
	// The returned styles should still reflect the dark palette
	// because the callback parameter is intentionally ignored.
	dark := New(true)
	light := New(false)

	fromDark := dark.Huh.Theme(false)  // pass false, should still get dark
	fromLight := light.Huh.Theme(true) // pass true, should still get light

	if fromDark == nil {
		t.Fatal("Theme(false) on dark Styles returned nil")
	}
	if fromLight == nil {
		t.Fatal("Theme(true) on light Styles returned nil")
	}

	// Verify the title colour matches the expected palette accent,
	// not the opposite palette. We compare the rendered output of
	// the title style — if huh's isDark parameter were used instead
	// of ours, the foreground colour would differ.
	//
	// Skip when lipgloss strips ANSI (e.g. TERM=dumb, NO_COLOR),
	// because both renders would collapse to plain "x".
	darkTitle := fromDark.Focused.Title.Render("x")
	lightTitle := fromLight.Focused.Title.Render("x")
	if darkTitle == "x" && lightTitle == "x" {
		t.Skip("colour output unavailable; cannot compare palette rendering")
	}
	if darkTitle == lightTitle {
		t.Error("dark and light huh themes produced identical title rendering; isDark parameter may not be ignored")
	}
}

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

	s := New(true)
	got := s.Picker.EmptyDirectory.Value()
	want := "No files in this directory."
	if got != want {
		t.Errorf("EmptyDirectory string = %q, want %q", got, want)
	}
}

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

	s := New(true)

	// ShortDesc and FullDesc should have no foreground set (they
	// inherit the terminal default). We verify by checking that the
	// style renders without injecting a colour sequence.
	plain := "test"
	if got := s.Help.ShortDesc.Render(plain); got != plain {
		t.Errorf("ShortDesc styled unexpectedly: got %q, want %q", got, plain)
	}
	if got := s.Help.FullDesc.Render(plain); got != plain {
		t.Errorf("FullDesc styled unexpectedly: got %q, want %q", got, plain)
	}
}

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

	if Cursor != "▸ " {
		t.Errorf("Cursor = %q, want %q", Cursor, "▸ ")
	}
}
