package app

import (
	"strings"
	"testing"

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

func fullScreen(ch string, w, h int) string {
	row := strings.Repeat(ch, w)
	rows := make([]string, h)
	for i := range rows {
		rows[i] = row
	}
	return strings.Join(rows, "\n")
}

// A composited modal must still fill the whole screen exactly (h lines, each w cols),
// so the alt-screen never shows a torn/short region around a "transparent" modal.
func TestCompositeOverlayGeometry(t *testing.T) {
	m := NewModel(nil)
	m.width, m.height = 40, 12
	m.lastBase = fullScreen("x", 40, 12)

	modal := lipgloss.NewStyle().Width(10).Border(lipgloss.RoundedBorder()).Render("hi\nthere")
	out := m.center(modal)

	lines := strings.Split(out, "\n")
	if len(lines) != 12 {
		t.Fatalf("height = %d, want 12", len(lines))
	}
	for i, ln := range lines {
		if w := ansi.StringWidth(ln); w != 40 {
			t.Fatalf("line %d visible width = %d, want 40", i, w)
		}
	}
}

// The idempotence guard: a modal that is already full-screen (a builder that centered
// internally, then got re-centered) must pass through unchanged — not get re-dimmed.
func TestCenterIdempotentOnFullScreen(t *testing.T) {
	m := NewModel(nil)
	m.width, m.height = 30, 8
	m.lastBase = fullScreen("y", 30, 8)

	full := fullScreen("M", 30, 8)
	if got := m.center(full); got != full {
		t.Fatal("center should pass a full-screen modal through unchanged")
	}
}
