package webui

import (
	"strings"
	"testing"
)

// ---- Toaster ----

// The whole point of Toaster over ToastProvider: it removes toasts by itself. On
// the server there is no clock (SetTimeout is a no-op), so nothing is scheduled —
// but the toast still renders, which is what SSR should show.
func TestToasterPushAndDismiss(t *testing.T) {
	tr := NewToaster(ToasterOptions{})

	id := tr.Success("Saved.")
	if len(tr.Toasts()) != 1 {
		t.Fatalf("Push added %d toasts, want 1", len(tr.Toasts()))
	}
	got := tr.Toasts()[0]
	if got.ID != id || got.Type != ToastSuccess || got.Message != "Saved." {
		t.Errorf("unexpected toast: %+v", got)
	}
	// An unset duration must become the default, NOT "forever": a toast that never
	// leaves is how a notification area silently fills up.
	if got.Duration != DefaultToastDuration {
		t.Errorf("Duration = %d, want the default %d", got.Duration, DefaultToastDuration)
	}
	if !got.ShowProgress {
		t.Error("an auto-dismissing toast should show its countdown")
	}

	tr.Dismiss(id)
	if len(tr.Toasts()) != 0 {
		t.Errorf("Dismiss left %d toasts", len(tr.Toasts()))
	}
}

func TestToasterSticky(t *testing.T) {
	tr := NewToaster(ToasterOptions{})
	tr.Push(Toast{Message: "stays", Duration: ToastSticky})

	got := tr.Toasts()[0]
	if got.Duration != ToastSticky {
		t.Errorf("Duration = %d, want ToastSticky", got.Duration)
	}
	// No countdown bar on something that is not counting down.
	if got.ShowProgress {
		t.Error("a sticky toast should not show a progress bar")
	}
}

func TestToasterIDsAreUnique(t *testing.T) {
	tr := NewToaster(ToasterOptions{})
	seen := map[string]bool{}
	for range 5 {
		id := tr.Info("x")
		if seen[id] {
			t.Fatalf("duplicate toast ID %q", id)
		}
		seen[id] = true
	}
	tr.Clear()
	if len(tr.Toasts()) != 0 {
		t.Error("Clear left toasts behind")
	}
}

func TestToasterRendersCountdownBar(t *testing.T) {
	tr := NewToaster(ToasterOptions{})
	tr.Success("Saved.")
	html := renderNode(tr.Render())

	// The bar is DECLARED at full width; the countdown is an imperative transition
	// from there to 0. If the declared width ever stopped being 100%, the bar would
	// start empty and the animation would be invisible.
	if !strings.Contains(html, "width:100%") {
		t.Errorf("countdown bar not declared at full width:\n%s", html)
	}
	if !strings.Contains(html, "circle-check") && !strings.Contains(html, "<path") {
		t.Error("the toast's icon did not render")
	}
}
