package messagewall

import (
	"strings"
	"testing"
)

func TestResolveBuildsScenes(t *testing.T) {
	request := ResolveRequest{
		Layout: Layout{
			Version: 1,
			CoordinateSpace: CoordinateSpace{
				Width:  200,
				Height: 100,
				Unit:   "grid",
			},
			FitMode: "cover",
			Slots: []Slot{
				{SlotID: "wall-r1-c2", X: 100, Y: 0, Width: 100, Height: 100},
				{SlotID: "wall-r1-c1", X: 0, Y: 0, Width: 100, Height: 100},
			},
		},
		Source:             "/media/banner.png",
		DurationSeconds:    30,
		LoadTimeoutSeconds: 12,
		OnError:            "skip",
	}

	result, err := Resolve(request)
	if err != nil {
		t.Fatalf("Resolve() error = %v", err)
	}

	if got, want := len(result.Scenes), 2; got != want {
		t.Fatalf("len(result.Scenes) = %d, want %d", got, want)
	}

	if got, want := result.Scenes[0].SlotID, "wall-r1-c1"; got != want {
		t.Fatalf("first SlotID = %s, want %s", got, want)
	}

	if got, want := result.Scenes[1].Crop.X, 100; got != want {
		t.Fatalf("second Crop.X = %d, want %d", got, want)
	}
}

func TestValidateRejectsOverlappingSlots(t *testing.T) {
	layout := Layout{
		Version: 1,
		CoordinateSpace: CoordinateSpace{
			Width:  100,
			Height: 100,
			Unit:   "grid",
		},
		FitMode: "cover",
		Slots: []Slot{
			{SlotID: "a", X: 0, Y: 0, Width: 60, Height: 60},
			{SlotID: "b", X: 50, Y: 0, Width: 50, Height: 50},
		},
	}

	if err := Validate(layout); err == nil {
		t.Fatal("Validate() error = nil, want overlap error")
	}
}

func TestValidateRejectsDocumentedInvalidLayouts(t *testing.T) {
	tests := []struct {
		name        string
		layout      Layout
		wantMessage string
	}{
		{
			name: "unsupported version",
			layout: Layout{
				Version:         2,
				CoordinateSpace: CoordinateSpace{Width: 100, Height: 100, Unit: "grid"},
				FitMode:         "cover",
				Slots:           []Slot{{SlotID: "a", X: 0, Y: 0, Width: 100, Height: 100}},
			},
			wantMessage: "unsupported layout version",
		},
		{
			name: "unsupported unit",
			layout: Layout{
				Version:         1,
				CoordinateSpace: CoordinateSpace{Width: 100, Height: 100, Unit: "pixel"},
				FitMode:         "cover",
				Slots:           []Slot{{SlotID: "a", X: 0, Y: 0, Width: 100, Height: 100}},
			},
			wantMessage: "unsupported coordinate_space unit",
		},
		{
			name: "unsupported fit mode",
			layout: Layout{
				Version:         1,
				CoordinateSpace: CoordinateSpace{Width: 100, Height: 100, Unit: "grid"},
				FitMode:         "stretch",
				Slots:           []Slot{{SlotID: "a", X: 0, Y: 0, Width: 100, Height: 100}},
			},
			wantMessage: "unsupported fit_mode",
		},
		{
			name: "empty slots",
			layout: Layout{
				Version:         1,
				CoordinateSpace: CoordinateSpace{Width: 100, Height: 100, Unit: "grid"},
				FitMode:         "cover",
			},
			wantMessage: "layout must contain at least one slot",
		},
		{
			name: "duplicate slot ids",
			layout: Layout{
				Version:         1,
				CoordinateSpace: CoordinateSpace{Width: 100, Height: 100, Unit: "grid"},
				FitMode:         "cover",
				Slots: []Slot{
					{SlotID: "a", X: 0, Y: 0, Width: 50, Height: 100},
					{SlotID: "a", X: 50, Y: 0, Width: 50, Height: 100},
				},
			},
			wantMessage: "duplicate slot_id",
		},
		{
			name: "slot exceeds bounds",
			layout: Layout{
				Version:         1,
				CoordinateSpace: CoordinateSpace{Width: 100, Height: 100, Unit: "grid"},
				FitMode:         "cover",
				Slots:           []Slot{{SlotID: "a", X: 60, Y: 0, Width: 50, Height: 100}},
			},
			wantMessage: "exceeds coordinate_space width",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			err := Validate(tt.layout)
			if err == nil {
				t.Fatal("Validate() error = nil, want validation error")
			}

			if !strings.Contains(err.Error(), tt.wantMessage) {
				t.Fatalf("Validate() error = %q, want message containing %q", err.Error(), tt.wantMessage)
			}
		})
	}
}
