package dashboardbuilder

import (
	"testing"
)

func TestApplyDefaults_VariableTypeDefaultsToDynamic(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{
			"svc": {Description: "service"},
		},
	}
	ApplyDefaults(d, nil, nil)

	v := d.Variables["svc"]
	if v.Type != VariableTypeDynamic {
		t.Errorf("expected type %q, got %q", VariableTypeDynamic, v.Type)
	}
	if v.Sort != SortASC {
		t.Errorf("expected sort %q for DYNAMIC, got %q", SortASC, v.Sort)
	}
}

func TestApplyDefaults_NonDynamicVariableSortDisabled(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{
			"q": {Type: VariableTypeQuery, QueryValue: "SELECT 1"},
		},
	}
	ApplyDefaults(d, nil, nil)

	if d.Variables["q"].Sort != SortDisabled {
		t.Errorf("expected sort %q, got %q", SortDisabled, d.Variables["q"].Sort)
	}
}

func TestApplyDefaults_VariableIDAutoGenerated(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{
			"v1": {Type: VariableTypeDynamic},
		},
	}
	ApplyDefaults(d, nil, nil)

	if d.Variables["v1"].ID == "" {
		t.Error("expected auto-generated ID, got empty string")
	}
}

func TestApplyDefaults_VariableNameFromKey(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{
			"my_var": {Type: VariableTypeDynamic},
		},
	}
	ApplyDefaults(d, nil, nil)

	if d.Variables["my_var"].Name != "my_var" {
		t.Errorf("expected name %q, got %q", "my_var", d.Variables["my_var"].Name)
	}
}

func TestApplyDefaults_DynamicVariableBoolDefaults(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{
			"svc": {Type: VariableTypeDynamic},
		},
	}
	// multiSelect and showALLOption not explicitly set.
	multiSelectSet := map[string]bool{}
	showALLSet := map[string]bool{}
	ApplyDefaults(d, multiSelectSet, showALLSet)

	v := d.Variables["svc"]
	if !v.MultiSelect {
		t.Error("expected multiSelect=true for DYNAMIC variable (not explicitly set)")
	}
	if !v.ShowALLOption {
		t.Error("expected showALLOption=true for DYNAMIC variable (not explicitly set)")
	}
}

func TestApplyDefaults_DynamicVariableBoolExplicitFalse(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{
			"svc": {Type: VariableTypeDynamic, MultiSelect: false, ShowALLOption: false},
		},
	}
	// Mark as explicitly set.
	multiSelectSet := map[string]bool{"svc": true}
	showALLSet := map[string]bool{"svc": true}
	ApplyDefaults(d, multiSelectSet, showALLSet)

	v := d.Variables["svc"]
	if v.MultiSelect {
		t.Error("expected multiSelect=false (explicitly set)")
	}
	if v.ShowALLOption {
		t.Error("expected showALLOption=false (explicitly set)")
	}
}

func TestApplyDefaults_WidgetDefaults(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{},
		Widgets: []WidgetOrRow{
			{PanelTypes: PanelTypeGraph, Title: "Test", Query: &Query{QueryType: QueryTypeBuilder}},
		},
	}
	ApplyDefaults(d, nil, nil)

	w := d.Widgets[0]
	if w.ID == "" {
		t.Error("expected auto-generated widget ID")
	}
	if w.Opacity != DefaultOpacity {
		t.Errorf("expected opacity %q, got %q", DefaultOpacity, w.Opacity)
	}
	if w.NullZeroValues != DefaultNullZeroValues {
		t.Errorf("expected nullZeroValues %q, got %q", DefaultNullZeroValues, w.NullZeroValues)
	}
	if w.TimePreferance != DefaultTimePreferance {
		t.Errorf("expected timePreferance %q, got %q", DefaultTimePreferance, w.TimePreferance)
	}
	if w.SoftMin == nil || *w.SoftMin != 0 {
		t.Error("expected softMin=0")
	}
	if w.SoftMax == nil || *w.SoftMax != 0 {
		t.Error("expected softMax=0")
	}
}

func TestApplyDefaults_RowWidgetSkipsDisplayDefaults(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{},
		Widgets: []WidgetOrRow{
			{PanelTypes: PanelTypeRow, Title: "Row"},
		},
	}
	ApplyDefaults(d, nil, nil)

	w := d.Widgets[0]
	if w.ID == "" {
		t.Error("expected auto-generated ID for row")
	}
	// Row should NOT have display defaults set.
	if w.Opacity != "" {
		t.Errorf("row should not have opacity set, got %q", w.Opacity)
	}
}

func TestApplyDefaults_VersionSet(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{},
	}
	ApplyDefaults(d, nil, nil)

	if d.Version != DashboardVersion {
		t.Errorf("expected version %q, got %q", DashboardVersion, d.Version)
	}
}

func TestApplyDefaults_AutoLayoutGenerated(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{},
		Widgets: []WidgetOrRow{
			{ID: "w1", PanelTypes: PanelTypeGraph, Title: "W1", Query: &Query{}},
			{ID: "w2", PanelTypes: PanelTypeGraph, Title: "W2", Query: &Query{}},
		},
	}
	ApplyDefaults(d, nil, nil)

	if len(d.Layout) != 2 {
		t.Fatalf("expected 2 layout items, got %d", len(d.Layout))
	}
	if d.Layout[0].I != "w1" || d.Layout[1].I != "w2" {
		t.Errorf("layout IDs mismatch: %v", d.Layout)
	}
}

func TestApplyDefaults_PanelMapInitialized(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{},
	}
	ApplyDefaults(d, nil, nil)

	if d.PanelMap == nil {
		t.Error("expected panelMap to be initialized")
	}
}

func TestApplyDefaults_VariableOrderAssigned(t *testing.T) {
	d := &DashboardData{
		Variables: map[string]*DashboardVariable{
			"a": {Type: VariableTypeDynamic},
			"b": {Type: VariableTypeDynamic},
		},
	}
	ApplyDefaults(d, nil, nil)

	for key, v := range d.Variables {
		if v.Order == nil {
			t.Errorf("expected order to be set for variable %q", key)
		}
	}
}
