package migration

import (
	"testing"
)

// copyMap creates a deep copy of a map[string]interface{} for testing
func copyMap(src map[string]interface{}) map[string]interface{} {
	dst := make(map[string]interface{})
	for k, v := range src {
		dst[k] = v
	}
	return dst
}

// assertPropertyRemoved checks that a property has been removed from the map
func assertPropertyRemoved(t *testing.T, obj map[string]interface{}, key string) {
	if _, exists := obj[key]; exists {
		t.Errorf("Property %s should have been removed but still exists", key)
	}
}

// assertPropertyValue checks that a property has the expected value
func assertPropertyValue(t *testing.T, obj map[string]interface{}, key string, expected interface{}) {
	if actual, exists := obj[key]; !exists {
		t.Errorf("Property %s should exist but is missing", key)
	} else if !compareValues(actual, expected) {
		t.Errorf("Property %s has wrong value. Expected: %v, Got: %v", key, expected, actual)
	}
}

// assertPropertiesExist checks that all expected properties exist with correct values
func assertPropertiesExist(t *testing.T, obj map[string]interface{}, expected map[string]interface{}) {
	for key, expectedValue := range expected {
		assertPropertyValue(t, obj, key, expectedValue)
	}
}

// assertPropertiesRemoved checks that all specified properties have been removed
func assertPropertiesRemoved(t *testing.T, obj map[string]interface{}, unwantedProps []string) {
	for _, prop := range unwantedProps {
		assertPropertyRemoved(t, obj, prop)
	}
}

func TestFrontendDefaultsCleanup(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "remove_dashboard_id_null",
			input: map[string]interface{}{
				"id":    nil,
				"title": "Test Dashboard",
			},
			expected: map[string]interface{}{
				"title": "Test Dashboard",
			},
		},
		{
			name: "remove_version_property",
			input: map[string]interface{}{
				"version": float64(123),
				"title":   "Test Dashboard",
			},
			expected: map[string]interface{}{
				"title": "Test Dashboard",
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			cleanupDashboardDefaults(dashboard)

			// Check that expected properties exist
			for key, expectedValue := range tt.expected {
				assertPropertyValue(t, dashboard, key, expectedValue)
			}

			// Check that version is always removed
			assertPropertyRemoved(t, dashboard, "version")

			// Check that id is removed when it was null in input
			if idValue, exists := tt.input["id"]; exists && idValue == nil {
				assertPropertyRemoved(t, dashboard, "id")
			}
		})
	}
}

func TestCleanupDashboardForSave(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "remove_non_persisted_properties",
			input: map[string]interface{}{
				"title":        "Test Dashboard",
				"meta":         map[string]interface{}{"canEdit": true},
				"events":       map[string]interface{}{},
				"originalTime": "2023-01-01",
				"variables":    map[string]interface{}{"list": []interface{}{}},
			},
			expected: map[string]interface{}{
				"title": "Test Dashboard",
				// meta, events, originalTime, variables should be removed
			},
		},
		{
			name: "remove_null_values",
			input: map[string]interface{}{
				"title":  "Test Dashboard",
				"gnetId": nil,
			},
			expected: map[string]interface{}{
				"title": "Test Dashboard",
				// gnetId should be removed
			},
		},
		{
			name: "cleanup_templating_and_panels",
			input: map[string]interface{}{
				"title": "Test Dashboard",
				"templating": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{
							"name":  "var1",
							"index": -1, // Should be removed
						},
					},
				},
				"panels": []interface{}{
					map[string]interface{}{
						"type":   "timeseries",
						"title":  "",                       // Default value, should be removed
						"events": map[string]interface{}{}, // Not persisted, should be removed
					},
				},
			},
			expected: map[string]interface{}{
				"title": "Test Dashboard",
				"templating": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{
							"name": "var1",
							// index should be removed
						},
					},
				},
				"panels": []interface{}{
					map[string]interface{}{
						"type": "timeseries",
						// title and events should be removed
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			cleanupDashboardForSave(dashboard)

			// Verify expected properties exist
			assertPropertiesExist(t, dashboard, tt.expected)

			// Verify unwanted properties are removed
			unwantedProps := []string{"meta", "events", "originalTime", "variables", "gnetId"}
			assertPropertiesRemoved(t, dashboard, unwantedProps)
		})
	}
}

func TestCleanupVariable(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "cleanup_query_variable",
			input: map[string]interface{}{
				"type":       "query",
				"name":       "var1",
				"datasource": nil,
				"index":      -1,
			},
			expected: map[string]interface{}{
				"type":    "query",
				"name":    "var1",
				"options": []interface{}{},
				// datasource and index should be removed
			},
		},
		{
			name: "cleanup_constant_variable",
			input: map[string]interface{}{
				"type":    "constant",
				"name":    "var2",
				"value":   "constant_value",
				"options": []interface{}{"option1"},
				"index":   -1,
			},
			expected: map[string]interface{}{
				"type":  "constant",
				"name":  "var2",
				"value": "constant_value",
				// options and index should be removed
			},
		},
		{
			name: "cleanup_datasource_variable",
			input: map[string]interface{}{
				"type":  "datasource",
				"name":  "var3",
				"index": -1,
			},
			expected: map[string]interface{}{
				"type":    "datasource",
				"name":    "var3",
				"options": []interface{}{},
				// index should be removed
			},
		},
		{
			name: "cleanup_custom_variable",
			input: map[string]interface{}{
				"type":    "custom",
				"name":    "var4",
				"options": []interface{}{"option1", "option2"},
				"index":   -1,
			},
			expected: map[string]interface{}{
				"type":    "custom",
				"name":    "var4",
				"options": []interface{}{"option1", "option2"},
				// index should be removed
			},
		},
		{
			name: "cleanup_textbox_variable",
			input: map[string]interface{}{
				"type":  "textbox",
				"name":  "var5",
				"value": "text_value",
				"index": -1,
			},
			expected: map[string]interface{}{
				"type":  "textbox",
				"name":  "var5",
				"value": "text_value",
				// index should be removed
			},
		},
		{
			name: "cleanup_adhoc_variable",
			input: map[string]interface{}{
				"type":    "adhoc",
				"name":    "var6",
				"filters": []interface{}{},
				"index":   -1,
			},
			expected: map[string]interface{}{
				"type":    "adhoc",
				"name":    "var6",
				"filters": []interface{}{},
				// index should be removed
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			variable := make(map[string]interface{})
			for k, v := range tt.input {
				variable[k] = v
			}

			cleanupVariable(variable)

			// Verify expected properties exist
			assertPropertiesExist(t, variable, tt.expected)

			// Verify unwanted properties are removed
			assertPropertyRemoved(t, variable, "index")
		})
	}
}

func TestCleanupPanels(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "filter_repeated_panels",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"type":  "timeseries",
						"title": "Panel 1",
					},
					map[string]interface{}{
						"type":          "table",
						"title":         "Panel 2",
						"repeatPanelId": 1, // Should be filtered out
					},
					map[string]interface{}{
						"type":          "graph",
						"title":         "Panel 3",
						"repeatedByRow": "row1", // Should be filtered out
					},
					map[string]interface{}{
						"type":  "stat",
						"title": "Panel 4",
					},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"type":  "timeseries",
						"title": "Panel 1",
					},
					map[string]interface{}{
						"type":  "stat",
						"title": "Panel 4",
					},
				},
			},
		},
		{
			name: "cleanup_panel_properties",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"type":       "timeseries",
						"title":      "",                                       // Default value, should be removed
						"events":     map[string]interface{}{},                 // Not persisted, should be removed
						"scopedVars": map[string]interface{}{"var1": "value1"}, // Should be removed
					},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"type": "timeseries",
						// title, events, scopedVars should be removed
					},
				},
			},
		},
		{
			name: "ensure_panels_property_exists",
			input: map[string]interface{}{
				"title": "Test Dashboard",
			},
			expected: map[string]interface{}{
				"title":  "Test Dashboard",
				"panels": []interface{}{},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			cleanupPanels(dashboard)

			// Verify expected properties exist
			assertPropertiesExist(t, dashboard, tt.expected)
		})
	}
}

func TestCleanupRowPanelProperties(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "remove_empty_repeat_from_row_panel",
			input: map[string]interface{}{
				"type":      "row",
				"title":     "Row Panel",
				"repeat":    "", // Empty string, should be removed
				"collapsed": false,
			},
			expected: map[string]interface{}{
				"type":      "row",
				"title":     "Row Panel",
				"collapsed": false, // Should be preserved
				// repeat should be removed
			},
		},
		{
			name: "preserve_non_empty_repeat_in_row_panel",
			input: map[string]interface{}{
				"type":      "row",
				"title":     "Row Panel",
				"repeat":    "server", // Non-empty, should be preserved
				"collapsed": false,
			},
			expected: map[string]interface{}{
				"type":      "row",
				"title":     "Row Panel",
				"repeat":    "server",
				"collapsed": false,
			},
		},
		{
			name: "no_changes_for_non_row_panel",
			input: map[string]interface{}{
				"type":   "timeseries",
				"title":  "Timeseries Panel",
				"repeat": "", // Should not be removed for non-row panels
			},
			expected: map[string]interface{}{
				"type":   "timeseries",
				"title":  "Timeseries Panel",
				"repeat": "", // Should be preserved
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			panel := make(map[string]interface{})
			for k, v := range tt.input {
				panel[k] = v
			}

			cleanupRowPanelProperties(panel)

			// Verify expected properties exist
			assertPropertiesExist(t, panel, tt.expected)
		})
	}
}

func TestCleanupFieldConfigDefaults(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		panel    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "remove_empty_custom_from_migrated_singlestat",
			input: map[string]interface{}{
				"custom": map[string]interface{}{},
				"color": map[string]interface{}{
					"mode":       "fixed",
					"fixedColor": "red",
				},
				"mappings": []interface{}{},
			},
			panel: map[string]interface{}{
				"autoMigrateFrom": "singlestat",
			},
			expected: map[string]interface{}{
				"color": map[string]interface{}{
					"mode":       "fixed",
					"fixedColor": "red",
				},
				"mappings": []interface{}{},
				// custom should be removed
			},
		},
		{
			name: "preserve_empty_custom_from_non_migrated_panel",
			input: map[string]interface{}{
				"custom": map[string]interface{}{},
				"color": map[string]interface{}{
					"mode":       "fixed",
					"fixedColor": "red",
				},
			},
			panel: map[string]interface{}{
				"type": "timeseries",
			},
			expected: map[string]interface{}{
				"custom": map[string]interface{}{}, // Should be preserved
				"color": map[string]interface{}{
					"mode":       "fixed",
					"fixedColor": "red",
				},
			},
		},
		{
			name: "preserve_non_empty_custom",
			input: map[string]interface{}{
				"custom": map[string]interface{}{
					"displayMode": "list",
				},
				"color": map[string]interface{}{
					"mode":       "fixed",
					"fixedColor": "red",
				},
			},
			panel: map[string]interface{}{
				"autoMigrateFrom": "singlestat",
			},
			expected: map[string]interface{}{
				"custom": map[string]interface{}{
					"displayMode": "list",
				},
				"color": map[string]interface{}{
					"mode":       "fixed",
					"fixedColor": "red",
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			defaults := make(map[string]interface{})
			for k, v := range tt.input {
				defaults[k] = v
			}

			panel := make(map[string]interface{})
			for k, v := range tt.panel {
				panel[k] = v
			}

			cleanupFieldConfigDefaults(defaults, panel)

			// Verify expected properties exist
			assertPropertiesExist(t, defaults, tt.expected)
		})
	}
}

// TestApplyFrontendDefaults tests the core dashboard defaults application logic
func TestApplyFrontendDefaults(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "apply_dashboard_defaults",
			input: map[string]interface{}{
				"schemaVersion": float64(42),
			},
			expected: map[string]interface{}{
				"title":                "No Title",
				"tags":                 []interface{}{},
				"timezone":             "",
				"weekStart":            "",
				"editable":             true,
				"graphTooltip":         float64(0),
				"time":                 map[string]interface{}{"from": "now-6h", "to": "now"},
				"timepicker":           map[string]interface{}{},
				"schemaVersion":        float64(42), // Preserved from input
				"fiscalYearStartMonth": float64(0),
				// version is NOT set as default - managed by backend metadata
				"links": []interface{}{},
			},
		},
		{
			name: "preserve_existing_values",
			input: map[string]interface{}{
				"title":    "Custom Title",
				"editable": false,
				"tags":     []interface{}{"tag1", "tag2"},
			},
			expected: map[string]interface{}{
				"title":                "Custom Title",                // Preserved
				"editable":             false,                         // Preserved
				"tags":                 []interface{}{"tag1", "tag2"}, // Preserved
				"timezone":             "",
				"weekStart":            "",
				"graphTooltip":         float64(0),
				"time":                 map[string]interface{}{"from": "now-6h", "to": "now"},
				"timepicker":           map[string]interface{}{},
				"schemaVersion":        float64(0),
				"fiscalYearStartMonth": float64(0),
				// version is NOT set as default - managed by backend metadata
				"links": []interface{}{},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			applyFrontendDefaults(dashboard)

			// Verify expected properties exist
			for key, expectedValue := range tt.expected {
				if actualValue, exists := dashboard[key]; !exists {
					t.Errorf("Property %s should exist but is missing", key)
				} else if !compareValues(actualValue, expectedValue) {
					t.Errorf("Property %s has wrong value. Expected: %v (type: %T), Got: %v (type: %T)", key, expectedValue, expectedValue, actualValue, actualValue)
				}
			}

			// Verify that version is NOT set as default (unless it was in input)
			if _, hadVersionInInput := tt.input["version"]; !hadVersionInInput {
				if _, hasVersion := dashboard["version"]; hasVersion {
					t.Errorf("Property version should not be set as default but was found")
				}
			}
		})
	}
}

// TestApplyPanelDefaults tests the core panel defaults application logic
func TestApplyPanelDefaults(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "apply_panel_defaults",
			input: map[string]interface{}{
				"type": "timeseries",
			},
			expected: map[string]interface{}{
				"type": "timeseries",
				"gridPos": map[string]interface{}{
					"x": float64(0), "y": float64(0), "h": float64(3), "w": float64(6),
				},
				"targets": []interface{}{
					map[string]interface{}{"refId": "A"},
				},
				"cachedPluginOptions": map[string]interface{}{},
				"transparent":         false,
				"options":             map[string]interface{}{},
				"links":               []interface{}{},
				"fieldConfig": map[string]interface{}{
					"defaults":  map[string]interface{}{},
					"overrides": []interface{}{},
				},
				"title": "",
			},
		},
		{
			name: "preserve_existing_panel_values",
			input: map[string]interface{}{
				"type":        "table",
				"title":       "Custom Panel",
				"transparent": true,
				"gridPos": map[string]interface{}{
					"x": float64(12), "y": float64(0), "h": float64(8), "w": float64(12),
				},
			},
			expected: map[string]interface{}{
				"type":        "table",
				"title":       "Custom Panel", // Preserved
				"transparent": true,           // Preserved
				"gridPos": map[string]interface{}{ // Preserved
					"x": float64(12), "y": float64(0), "h": float64(8), "w": float64(12),
				},
				"targets": []interface{}{
					map[string]interface{}{"refId": "A"},
				},
				"cachedPluginOptions": map[string]interface{}{},
				"options":             map[string]interface{}{},
				"links":               []interface{}{},
				"fieldConfig": map[string]interface{}{
					"defaults":  map[string]interface{}{},
					"overrides": []interface{}{},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			panel := make(map[string]interface{})
			for k, v := range tt.input {
				panel[k] = v
			}

			applyPanelDefaults(panel)

			// Verify expected properties exist
			assertPropertiesExist(t, panel, tt.expected)
		})
	}
}

// TestCleanupPanelForSave tests the core panel cleanup logic for save model
func TestTransformationsArrayContextAwareLogic(t *testing.T) {
	tests := []struct {
		name        string
		input       map[string]interface{}
		isNested    bool
		hasOriginal bool
		expected    map[string]interface{}
	}{
		{
			name: "top_level_panel_removes_empty_transformations",
			input: map[string]interface{}{
				"type":            "timeseries",
				"title":           "Top-level Panel",
				"transformations": []interface{}{},
			},
			isNested:    false,
			hasOriginal: true, // Had transformations in original input
			expected: map[string]interface{}{
				"type":  "timeseries",
				"title": "Top-level Panel",
				// transformations removed for top-level panels
			},
		},
		{
			name: "nested_panel_preserves_empty_transformations",
			input: map[string]interface{}{
				"type":            "timeseries",
				"title":           "Nested Panel",
				"transformations": []interface{}{},
			},
			isNested:    true,
			hasOriginal: true, // Had transformations in original input
			expected: map[string]interface{}{
				"type":            "timeseries",
				"title":           "Nested Panel",
				"transformations": []interface{}{}, // preserved for nested panels
			},
		},
		{
			name: "nested_panel_removes_added_transformations",
			input: map[string]interface{}{
				"type":            "table",
				"title":           "Nested Panel Without Original",
				"transformations": []interface{}{},
			},
			isNested:    true,
			hasOriginal: false, // Did NOT have transformations in original input
			expected: map[string]interface{}{
				"type":  "table",
				"title": "Nested Panel Without Original",
				// transformations removed - wasn't in original input
			},
		},
		{
			name: "preserve_non_empty_transformations",
			input: map[string]interface{}{
				"type":  "timeseries",
				"title": "Panel with actual transformations",
				"transformations": []interface{}{
					map[string]interface{}{
						"id": "reduce",
						"options": map[string]interface{}{
							"reducers": []interface{}{"mean"},
						},
					},
				},
			},
			isNested:    false,
			hasOriginal: true,
			expected: map[string]interface{}{
				"type":  "timeseries",
				"title": "Panel with actual transformations",
				"transformations": []interface{}{
					map[string]interface{}{
						"id": "reduce",
						"options": map[string]interface{}{
							"reducers": []interface{}{"mean"},
						},
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Create a copy of input for testing
			panel := make(map[string]interface{})
			for k, v := range tt.input {
				panel[k] = v
			}

			// Set the original transformations marker if needed
			if tt.hasOriginal {
				panel["_originallyHadTransformations"] = true
			}

			// Apply the cleanup logic
			cleanupPanelForSaveWithContext(panel, tt.isNested)

			// Verify the result
			if !compareValues(panel, tt.expected) {
				t.Errorf("Test %s failed.\nExpected: %+v\nGot: %+v", tt.name, tt.expected, panel)
			}
		})
	}
}

func TestTrackOriginalFieldConfigCustom(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "track_top_level_panel_with_fieldConfig_custom",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":   1,
						"type": "timeseries",
						"fieldConfig": map[string]interface{}{
							"defaults": map[string]interface{}{
								"custom": map[string]interface{}{},
							},
							"overrides": []interface{}{},
						},
					},
					map[string]interface{}{
						"id":   2,
						"type": "table",
						"fieldConfig": map[string]interface{}{
							"defaults":  map[string]interface{}{},
							"overrides": []interface{}{},
						},
					},
					map[string]interface{}{
						"id":    3,
						"type":  "stat",
						"title": "Panel without fieldConfig",
					},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":   1,
						"type": "timeseries",
						"fieldConfig": map[string]interface{}{
							"defaults": map[string]interface{}{
								"custom": map[string]interface{}{},
							},
							"overrides": []interface{}{},
						},
						"_originallyHadFieldConfigCustom": true, // marker added
					},
					map[string]interface{}{
						"id":   2,
						"type": "table",
						"fieldConfig": map[string]interface{}{
							"defaults":  map[string]interface{}{},
							"overrides": []interface{}{},
						},
						// no marker added - no custom object
					},
					map[string]interface{}{
						"id":    3,
						"type":  "stat",
						"title": "Panel without fieldConfig",
						// no marker added - no fieldConfig
					},
				},
			},
		},
		{
			name: "track_nested_panels_in_row_with_fieldConfig_custom",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":    1,
						"type":  "row",
						"title": "Row Panel",
						"panels": []interface{}{
							map[string]interface{}{
								"id":   10,
								"type": "singlestat",
								"fieldConfig": map[string]interface{}{
									"defaults": map[string]interface{}{
										"custom": map[string]interface{}{},
									},
									"overrides": []interface{}{},
								},
							},
							map[string]interface{}{
								"id":   11,
								"type": "graph",
								"fieldConfig": map[string]interface{}{
									"defaults": map[string]interface{}{
										"unit": "bytes",
									},
									"overrides": []interface{}{},
								},
							},
						},
					},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":    1,
						"type":  "row",
						"title": "Row Panel",
						"panels": []interface{}{
							map[string]interface{}{
								"id":   10,
								"type": "singlestat",
								"fieldConfig": map[string]interface{}{
									"defaults": map[string]interface{}{
										"custom": map[string]interface{}{},
									},
									"overrides": []interface{}{},
								},
								"_originallyHadFieldConfigCustom": true, // marker added to nested panel
							},
							map[string]interface{}{
								"id":   11,
								"type": "graph",
								"fieldConfig": map[string]interface{}{
									"defaults": map[string]interface{}{
										"unit": "bytes",
									},
									"overrides": []interface{}{},
								},
								// no marker added - no custom object
							},
						},
					},
				},
			},
		},
		{
			name: "track_panels_with_non_empty_custom",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":   1,
						"type": "timeseries",
						"fieldConfig": map[string]interface{}{
							"defaults": map[string]interface{}{
								"custom": map[string]interface{}{
									"axisPlacement": "left",
								},
							},
							"overrides": []interface{}{},
						},
					},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":   1,
						"type": "timeseries",
						"fieldConfig": map[string]interface{}{
							"defaults": map[string]interface{}{
								"custom": map[string]interface{}{
									"axisPlacement": "left",
								},
							},
							"overrides": []interface{}{},
						},
						"_originallyHadFieldConfigCustom": true, // marker added for non-empty custom
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Create a deep copy of input for testing
			dashboard := deepCopy(tt.input).(map[string]interface{})

			// Apply the tracking logic
			trackOriginalFieldConfigCustom(dashboard)

			// Verify the result
			if !compareValues(dashboard, tt.expected) {
				t.Errorf("Test %s failed.\nExpected: %+v\nGot: %+v", tt.name, tt.expected, dashboard)
			}
		})
	}
}

func TestTrackOriginalTransformations(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "track_top_level_panel_with_transformations",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":              1,
						"type":            "timeseries",
						"title":           "Panel with transformations",
						"transformations": []interface{}{},
					},
					map[string]interface{}{
						"id":    2,
						"type":  "table",
						"title": "Panel without transformations",
					},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":                            1,
						"type":                          "timeseries",
						"title":                         "Panel with transformations",
						"transformations":               []interface{}{},
						"_originallyHadTransformations": true, // marker added
					},
					map[string]interface{}{
						"id":    2,
						"type":  "table",
						"title": "Panel without transformations",
						// no marker added
					},
				},
			},
		},
		{
			name: "track_nested_panels_in_row",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":    1,
						"type":  "row",
						"title": "Row Panel",
						"panels": []interface{}{
							map[string]interface{}{
								"id":              10,
								"type":            "timeseries",
								"title":           "Nested Panel with transformations",
								"transformations": []interface{}{},
							},
							map[string]interface{}{
								"id":    11,
								"type":  "table",
								"title": "Nested Panel without transformations",
							},
						},
					},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":    1,
						"type":  "row",
						"title": "Row Panel",
						"panels": []interface{}{
							map[string]interface{}{
								"id":                            10,
								"type":                          "timeseries",
								"title":                         "Nested Panel with transformations",
								"transformations":               []interface{}{},
								"_originallyHadTransformations": true, // marker added to nested panel
							},
							map[string]interface{}{
								"id":    11,
								"type":  "table",
								"title": "Nested Panel without transformations",
								// no marker added
							},
						},
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Create a deep copy of input for testing
			dashboard := deepCopy(tt.input).(map[string]interface{})

			// Apply the tracking logic
			trackOriginalTransformations(dashboard)

			// Verify the result
			if !compareValues(dashboard, tt.expected) {
				t.Errorf("Test %s failed.\nExpected: %+v\nGot: %+v", tt.name, tt.expected, dashboard)
			}
		})
	}
}

func TestCleanupPanelForSavePreservesOriginalFieldConfigCustom(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "preserve_empty_custom_when_originally_present",
			input: map[string]interface{}{
				"type": "singlestat",
				"fieldConfig": map[string]interface{}{
					"defaults": map[string]interface{}{
						"custom": map[string]interface{}{}, // Empty but originally present
					},
					"overrides": []interface{}{},
				},
				"_originallyHadFieldConfigCustom": true, // Marker indicating it was originally present
			},
			expected: map[string]interface{}{
				"type":            "stat",       // Auto-migrated from singlestat
				"autoMigrateFrom": "singlestat", // Auto-migration marker
				"fieldConfig": map[string]interface{}{
					"defaults": map[string]interface{}{
						"custom": map[string]interface{}{}, // Should be preserved
					},
					"overrides": []interface{}{},
				},
			},
		},
		{
			name: "remove_empty_custom_when_not_originally_present",
			input: map[string]interface{}{
				"type": "timeseries",
				"fieldConfig": map[string]interface{}{
					"defaults": map[string]interface{}{
						"custom": map[string]interface{}{}, // Empty and not originally present
					},
					"overrides": []interface{}{},
				},
				// No marker - custom was not originally present
			},
			expected: map[string]interface{}{
				"type": "timeseries",
				// fieldConfig should be removed entirely as it matches defaults
			},
		},
		{
			name: "preserve_non_empty_custom_regardless_of_marker",
			input: map[string]interface{}{
				"type": "table",
				"fieldConfig": map[string]interface{}{
					"defaults": map[string]interface{}{
						"custom": map[string]interface{}{
							"displayMode": "list",
						},
					},
					"overrides": []interface{}{},
				},
			},
			expected: map[string]interface{}{
				"type": "table",
				"fieldConfig": map[string]interface{}{
					"defaults": map[string]interface{}{
						"custom": map[string]interface{}{
							"displayMode": "list",
						},
					},
					"overrides": []interface{}{},
				},
			},
		},
		{
			name: "add_custom_when_originally_present_but_missing",
			input: map[string]interface{}{
				"type": "stat",
				"fieldConfig": map[string]interface{}{
					"defaults":  map[string]interface{}{}, // custom missing
					"overrides": []interface{}{},
				},
				"_originallyHadFieldConfigCustom": true, // But marker indicates it was originally present
			},
			expected: map[string]interface{}{
				"type": "stat",
				"fieldConfig": map[string]interface{}{
					"defaults": map[string]interface{}{
						"custom": map[string]interface{}{}, // Should be added back
					},
					"overrides": []interface{}{},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			panel := make(map[string]interface{})
			for k, v := range tt.input {
				panel[k] = v
			}

			cleanupPanelForSaveWithContext(panel, false)

			// Verify expected properties exist
			for key, expectedValue := range tt.expected {
				if actualValue, exists := panel[key]; !exists {
					t.Errorf("Property %s should exist but is missing", key)
				} else if !compareValues(actualValue, expectedValue) {
					t.Errorf("Property %s has wrong value. Expected: %v, Got: %v", key, expectedValue, actualValue)
				}
			}

			// Verify internal markers are cleaned up
			assertPropertyRemoved(t, panel, "_originallyHadFieldConfigCustom")
		})
	}
}

func TestCleanupPanelForSave(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "remove_not_persisted_properties",
			input: map[string]interface{}{
				"type":                "timeseries",
				"title":               "Test Panel",
				"events":              map[string]interface{}{},
				"isViewing":           true,
				"cachedPluginOptions": map[string]interface{}{"test": "value"},
				"scopedVars":          map[string]interface{}{"var1": "value1"},
			},
			expected: map[string]interface{}{
				"type":  "timeseries",
				"title": "Test Panel",
				// events, isViewing, cachedPluginOptions, scopedVars should be removed
			},
		},
		{
			name: "remove_default_values",
			input: map[string]interface{}{
				"type":        "table",
				"title":       "",                       // Default value
				"transparent": false,                    // Default value
				"options":     map[string]interface{}{}, // Default value
				"links":       []interface{}{},          // Default value
			},
			expected: map[string]interface{}{
				"type": "table",
				// title, transparent, options, links should be removed as they match defaults
			},
		},
		{
			name: "preserve_non_default_values",
			input: map[string]interface{}{
				"type":        "timeseries",                              // Use timeseries to avoid auto-migration
				"title":       "Custom Title",                            // Non-default
				"transparent": true,                                      // Non-default
				"options":     map[string]interface{}{"custom": "value"}, // Non-default
			},
			expected: map[string]interface{}{
				"type":        "timeseries",
				"title":       "Custom Title",
				"transparent": true,
				"options":     map[string]interface{}{"custom": "value"},
			},
		},
		{
			name: "remove_empty_transformations_array_top_level",
			input: map[string]interface{}{
				"type":            "timeseries",
				"title":           "Test Panel",
				"transformations": []interface{}{}, // Empty array should be removed for top-level panels
			},
			expected: map[string]interface{}{
				"type":  "timeseries",
				"title": "Test Panel",
				// transformations should be removed for top-level panels
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			panel := make(map[string]interface{})
			for k, v := range tt.input {
				panel[k] = v
			}

			cleanupPanelForSaveWithContext(panel, false)

			// Verify expected properties exist
			assertPropertiesExist(t, panel, tt.expected)

			// Verify unwanted properties are removed
			unwantedProps := []string{"events", "isViewing", "cachedPluginOptions", "scopedVars"}
			assertPropertiesRemoved(t, panel, unwantedProps)
		})
	}
}

// TestApplyPanelAutoMigration tests the core panel auto-migration logic
func TestApplyPanelAutoMigration(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "migrate_graph_to_timeseries",
			input: map[string]interface{}{
				"type": "graph",
			},
			expected: map[string]interface{}{
				"type":            "timeseries",
				"autoMigrateFrom": "graph",
			},
		},
		{
			name: "migrate_graph_to_barchart",
			input: map[string]interface{}{
				"type": "graph",
				"xaxis": map[string]interface{}{
					"mode": "series",
				},
			},
			expected: map[string]interface{}{
				"type":            "barchart",
				"autoMigrateFrom": "graph",
			},
		},
		{
			name: "migrate_graph_to_bargauge",
			input: map[string]interface{}{
				"type": "graph",
				"xaxis": map[string]interface{}{
					"mode": "series",
				},
				"legend": map[string]interface{}{
					"values": true,
				},
			},
			expected: map[string]interface{}{
				"type":            "bargauge",
				"autoMigrateFrom": "graph",
			},
		},
		{
			name: "migrate_singlestat_to_stat",
			input: map[string]interface{}{
				"type": "singlestat",
			},
			expected: map[string]interface{}{
				"type":            "stat",
				"autoMigrateFrom": "singlestat",
			},
		},
		{
			name: "migrate_table_old_to_table",
			input: map[string]interface{}{
				"type": "table-old",
			},
			expected: map[string]interface{}{
				"type":            "table",
				"autoMigrateFrom": "table-old",
			},
		},
		{
			name: "no_migration_for_modern_panels",
			input: map[string]interface{}{
				"type": "timeseries",
			},
			expected: map[string]interface{}{
				"type": "timeseries",
				// No autoMigrateFrom should be added
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			panel := make(map[string]interface{})
			for k, v := range tt.input {
				panel[k] = v
			}

			applyPanelAutoMigration(panel)

			// Verify expected properties exist
			assertPropertiesExist(t, panel, tt.expected)

			// Verify no unexpected autoMigrateFrom is added
			if _, hasAutoMigrate := tt.expected["autoMigrateFrom"]; !hasAutoMigrate {
				if _, exists := panel["autoMigrateFrom"]; exists {
					t.Errorf("autoMigrateFrom should not be added for this panel type")
				}
			}
		})
	}
}

// TestRemoveNullValuesRecursively tests the core null value removal logic
func TestRemoveNullValuesRecursively(t *testing.T) {
	tests := []struct {
		name     string
		input    interface{}
		expected interface{}
	}{
		{
			name: "remove_null_values_from_map",
			input: map[string]interface{}{
				"title": "Test",
				"id":    nil,
				"config": map[string]interface{}{
					"enabled": true,
					"value":   nil,
				},
			},
			expected: map[string]interface{}{
				"title": "Test",
				"config": map[string]interface{}{
					"enabled": true,
				},
			},
		},
		{
			name: "process_array_elements",
			input: []interface{}{
				"item1",
				nil,
				"item2",
				map[string]interface{}{
					"key":  "value",
					"null": nil,
				},
			},
			expected: []interface{}{
				"item1",
				nil, // Null values in arrays are NOT removed by the current implementation
				"item2",
				map[string]interface{}{
					"key": "value",
					// null key should be removed from nested map
				},
			},
		},
		{
			name: "preserve_non_null_values",
			input: map[string]interface{}{
				"string": "value",
				"number": 42,
				"bool":   true,
				"array":  []interface{}{1, 2, 3},
			},
			expected: map[string]interface{}{
				"string": "value",
				"number": 42,
				"bool":   true,
				"array":  []interface{}{1, 2, 3},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Create a copy of the input to avoid modifying the original
			data := deepCopy(tt.input)

			removeNullValuesRecursively(data)

			if !compareValues(data, tt.expected) {
				t.Errorf("Null value removal failed. Expected: %v, Got: %v", tt.expected, data)
			}
		})
	}
}

// TestIsEqual tests the core value equality comparison logic
func TestIsEqual(t *testing.T) {
	tests := []struct {
		name     string
		a        interface{}
		b        interface{}
		expected bool
	}{
		{
			name:     "equal_strings",
			a:        "test",
			b:        "test",
			expected: true,
		},
		{
			name:     "different_strings",
			a:        "test1",
			b:        "test2",
			expected: false,
		},
		{
			name:     "equal_numbers",
			a:        float64(42),
			b:        float64(42),
			expected: true,
		},
		{
			name:     "equal_booleans",
			a:        true,
			b:        true,
			expected: true,
		},
		{
			name:     "equal_arrays",
			a:        []interface{}{float64(1), float64(2), float64(3)},
			b:        []interface{}{float64(1), float64(2), float64(3)},
			expected: true,
		},
		{
			name:     "different_arrays",
			a:        []interface{}{float64(1), float64(2), float64(3)},
			b:        []interface{}{float64(1), float64(2), float64(4)},
			expected: false,
		},
		{
			name:     "equal_maps",
			a:        map[string]interface{}{"key": "value"},
			b:        map[string]interface{}{"key": "value"},
			expected: true,
		},
		{
			name:     "different_maps",
			a:        map[string]interface{}{"key": "value1"},
			b:        map[string]interface{}{"key": "value2"},
			expected: false,
		},
		{
			name:     "nil_values",
			a:        nil,
			b:        nil,
			expected: true,
		},
		{
			name:     "nil_and_value",
			a:        nil,
			b:        "test",
			expected: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := isEqual(tt.a, tt.b)
			if result != tt.expected {
				t.Errorf("isEqual(%v, %v) = %v, expected %v", tt.a, tt.b, result, tt.expected)
			}
		})
	}
}

// Helper function to compare values recursively
func compareValues(actual, expected interface{}) bool {
	if actual == nil && expected == nil {
		return true
	}
	if actual == nil || expected == nil {
		return false
	}

	actualMap, actualOk := actual.(map[string]interface{})
	expectedMap, expectedOk := expected.(map[string]interface{})

	if actualOk && expectedOk {
		if len(actualMap) != len(expectedMap) {
			return false
		}
		for key, expectedValue := range expectedMap {
			actualValue, exists := actualMap[key]
			if !exists || !compareValues(actualValue, expectedValue) {
				return false
			}
		}
		return true
	}

	actualSlice, actualSliceOk := actual.([]interface{})
	expectedSlice, expectedSliceOk := expected.([]interface{})

	if actualSliceOk && expectedSliceOk {
		if len(actualSlice) != len(expectedSlice) {
			return false
		}
		for i, expectedValue := range expectedSlice {
			if !compareValues(actualSlice[i], expectedValue) {
				return false
			}
		}
		return true
	}

	return actual == expected
}

// Helper function to deep copy interface{}
func deepCopy(src interface{}) interface{} {
	switch v := src.(type) {
	case map[string]interface{}:
		dst := make(map[string]interface{})
		for k, val := range v {
			dst[k] = deepCopy(val)
		}
		return dst
	case []interface{}:
		dst := make([]interface{}, len(v))
		for i, val := range v {
			dst[i] = deepCopy(val)
		}
		return dst
	default:
		return src
	}
}

func TestEnsureTemplatingExists(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "create_templating_when_missing",
			input: map[string]interface{}{
				"title": "Test Dashboard",
			},
			expected: map[string]interface{}{
				"title": "Test Dashboard",
				"templating": map[string]interface{}{
					"list": []interface{}{},
				},
			},
		},
		{
			name: "add_list_to_existing_templating",
			input: map[string]interface{}{
				"templating": map[string]interface{}{
					"enable": true,
				},
			},
			expected: map[string]interface{}{
				"templating": map[string]interface{}{
					"enable": true,
					"list":   []interface{}{},
				},
			},
		},
		{
			name: "preserve_existing_templating",
			input: map[string]interface{}{
				"templating": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{"name": "var1"},
					},
				},
			},
			expected: map[string]interface{}{
				"templating": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{"name": "var1"},
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			ensureTemplatingExists(dashboard)

			// Verify expected properties exist
			assertPropertiesExist(t, dashboard, tt.expected)
		})
	}
}

func TestEnsureAnnotationsExist(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "create_annotations_when_missing",
			input: map[string]interface{}{
				"title": "Test Dashboard",
			},
			expected: map[string]interface{}{
				"title": "Test Dashboard",
				"annotations": map[string]interface{}{
					"list": []interface{}{},
				},
			},
		},
		{
			name: "add_list_to_existing_annotations",
			input: map[string]interface{}{
				"annotations": map[string]interface{}{
					"enable": true,
				},
			},
			expected: map[string]interface{}{
				"annotations": map[string]interface{}{
					"enable": true,
					"list":   []interface{}{},
				},
			},
		},
		{
			name: "preserve_existing_annotations",
			input: map[string]interface{}{
				"annotations": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{"name": "annotation1"},
					},
				},
			},
			expected: map[string]interface{}{
				"annotations": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{"name": "annotation1"},
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			ensureAnnotationsExist(dashboard)

			// Verify expected properties exist
			assertPropertiesExist(t, dashboard, tt.expected)
		})
	}
}

func TestEnsurePanelsHaveUniqueIds(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "assign_ids_to_panels_without_ids",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"type": "timeseries"},
					map[string]interface{}{"type": "table"},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"type": "timeseries", "id": float64(1)},
					map[string]interface{}{"type": "table", "id": float64(2)},
				},
			},
		},
		{
			name: "fix_duplicate_ids",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"type": "timeseries", "id": float64(1)},
					map[string]interface{}{"type": "table", "id": float64(1)}, // Duplicate
					map[string]interface{}{"type": "graph", "id": float64(2)},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"type": "timeseries", "id": float64(1)},
					map[string]interface{}{"type": "table", "id": float64(3)}, // Fixed duplicate
					map[string]interface{}{"type": "graph", "id": float64(2)},
				},
			},
		},
		{
			name: "preserve_valid_ids",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"type": "timeseries", "id": float64(5)},
					map[string]interface{}{"type": "table", "id": float64(10)},
				},
			},
			expected: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"type": "timeseries", "id": float64(5)},
					map[string]interface{}{"type": "table", "id": float64(10)},
				},
			},
		},
		{
			name: "fix_duplicate_ids_in_rows",
			input: map[string]interface{}{
				"rows": []interface{}{
					map[string]interface{}{
						"panels": []interface{}{
							map[string]interface{}{"type": "timeseries", "id": float64(1)},
							map[string]interface{}{"type": "table", "id": float64(5)},
						},
					},
					map[string]interface{}{
						"panels": []interface{}{
							map[string]interface{}{"type": "stat", "id": float64(1)},
							map[string]interface{}{"type": "gauge", "id": float64(5)},
						},
					},
				},
			},
			expected: map[string]interface{}{
				"rows": []interface{}{
					map[string]interface{}{
						"panels": []interface{}{
							map[string]interface{}{"type": "timeseries", "id": float64(1)},
							map[string]interface{}{"type": "table", "id": float64(5)},
						},
					},
					map[string]interface{}{
						"panels": []interface{}{
							map[string]interface{}{"type": "stat", "id": float64(6)},
							map[string]interface{}{"type": "gauge", "id": float64(7)},
						},
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			EnsurePanelsHaveUniqueIds(dashboard)

			// Verify expected properties exist
			assertPropertiesExist(t, dashboard, tt.expected)
		})
	}
}

func TestEnsureQueryIds(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "assign_refIds_to_targets_without_refIds",
			input: map[string]interface{}{
				"targets": []interface{}{
					map[string]interface{}{"expr": "up"},
					map[string]interface{}{"expr": "rate(up[5m])"},
				},
			},
			expected: map[string]interface{}{
				"targets": []interface{}{
					map[string]interface{}{"expr": "up", "refId": "A"},
					map[string]interface{}{"expr": "rate(up[5m])", "refId": "B"},
				},
			},
		},
		{
			name: "preserve_existing_refIds",
			input: map[string]interface{}{
				"targets": []interface{}{
					map[string]interface{}{"expr": "up", "refId": "A"},
					map[string]interface{}{"expr": "rate(up[5m])", "refId": "B"},
				},
			},
			expected: map[string]interface{}{
				"targets": []interface{}{
					map[string]interface{}{"expr": "up", "refId": "A"},
					map[string]interface{}{"expr": "rate(up[5m])", "refId": "B"},
				},
			},
		},
		{
			name: "assign_refIds_to_mixed_targets",
			input: map[string]interface{}{
				"targets": []interface{}{
					map[string]interface{}{"expr": "up", "refId": "A"},
					map[string]interface{}{"expr": "rate(up[5m])"}, // Missing refId
					map[string]interface{}{"expr": "sum(up)", "refId": "C"},
				},
			},
			expected: map[string]interface{}{
				"targets": []interface{}{
					map[string]interface{}{"expr": "up", "refId": "A"},
					map[string]interface{}{"expr": "rate(up[5m])", "refId": "B"}, // Assigned
					map[string]interface{}{"expr": "sum(up)", "refId": "C"},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			panel := make(map[string]interface{})
			for k, v := range tt.input {
				panel[k] = v
			}

			ensureQueryIds(panel)

			// Verify expected properties exist
			assertPropertiesExist(t, panel, tt.expected)
		})
	}
}

func TestAddBuiltInAnnotationQuery(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "add_built_in_annotation_when_none_exists",
			input: map[string]interface{}{
				"annotations": map[string]interface{}{
					"list": []interface{}{},
				},
			},
			expected: map[string]interface{}{
				"annotations": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{
							"datasource": map[string]interface{}{
								"uid":  "-- Grafana --",
								"type": "grafana",
							},
							"name":      "Annotations & Alerts",
							"type":      "dashboard",
							"iconColor": "rgba(0, 211, 255, 1)",
							"enable":    true,
							"hide":      true,
							"builtIn":   float64(1),
						},
					},
				},
			},
		},
		{
			name: "preserve_existing_built_in_annotation",
			input: map[string]interface{}{
				"annotations": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{
							"name":    "Annotations & Alerts",
							"builtIn": float64(1),
						},
					},
				},
			},
			expected: map[string]interface{}{
				"annotations": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{
							"name":    "Annotations & Alerts",
							"builtIn": float64(1),
						},
					},
				},
			},
		},
		{
			name: "add_built_in_annotation_with_existing_custom_annotations",
			input: map[string]interface{}{
				"annotations": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{
							"name": "Custom Annotation",
							"type": "tags",
						},
					},
				},
			},
			expected: map[string]interface{}{
				"annotations": map[string]interface{}{
					"list": []interface{}{
						map[string]interface{}{
							"datasource": map[string]interface{}{
								"uid":  "-- Grafana --",
								"type": "grafana",
							},
							"name":      "Annotations & Alerts",
							"type":      "dashboard",
							"iconColor": "rgba(0, 211, 255, 1)",
							"enable":    true,
							"hide":      true,
							"builtIn":   float64(1),
						},
						map[string]interface{}{
							"name": "Custom Annotation",
							"type": "tags",
						},
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			addBuiltInAnnotationQuery(dashboard)

			// Verify expected properties exist
			assertPropertiesExist(t, dashboard, tt.expected)
		})
	}
}

func TestInitMeta(t *testing.T) {
	tests := []struct {
		name     string
		input    map[string]interface{}
		expected map[string]interface{}
	}{
		{
			name: "init_meta_with_defaults",
			input: map[string]interface{}{
				"editable": true,
			},
			expected: map[string]interface{}{
				"editable": true,
				"meta": map[string]interface{}{
					"canShare":               true,
					"canSave":                true,
					"canStar":                true,
					"canEdit":                true,
					"canDelete":              true,
					"showSettings":           true,
					"canMakeEditable":        false,
					"hasUnsavedFolderChange": false,
				},
			},
		},
		{
			name: "init_meta_for_non_editable_dashboard",
			input: map[string]interface{}{
				"editable": false,
			},
			expected: map[string]interface{}{
				"editable": false,
				"meta": map[string]interface{}{
					"canShare":               true,
					"canSave":                false, // Restricted for non-editable
					"canStar":                true,
					"canEdit":                false, // Restricted for non-editable
					"canDelete":              false, // Restricted for non-editable
					"showSettings":           true,  // Set before canEdit is restricted (current implementation behavior)
					"canMakeEditable":        true,  // Can make editable
					"hasUnsavedFolderChange": false,
				},
			},
		},
		{
			name: "preserve_existing_meta",
			input: map[string]interface{}{
				"editable": true,
				"meta": map[string]interface{}{
					"canShare": false, // Custom value
				},
			},
			expected: map[string]interface{}{
				"editable": true,
				"meta": map[string]interface{}{
					"canShare":               false, // Preserved
					"canSave":                true,
					"canStar":                true,
					"canEdit":                true,
					"canDelete":              true,
					"showSettings":           true,
					"canMakeEditable":        false,
					"hasUnsavedFolderChange": false,
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			dashboard := copyMap(tt.input)

			initMeta(dashboard)

			// Verify expected properties exist
			assertPropertiesExist(t, dashboard, tt.expected)
		})
	}
}

func TestGetPanels(t *testing.T) {
	tests := []struct {
		name           string
		input          map[string]interface{}
		expectedIDs    []int
		expectedTitles []string
	}{
		{
			name: "top-level panels only",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"id": 1, "title": "Panel 1", "type": "stat"},
					map[string]interface{}{"id": 2, "title": "Panel 2", "type": "graph"},
				},
			},
			expectedIDs:    []int{1, 2},
			expectedTitles: []string{"Panel 1", "Panel 2"},
		},
		{
			name: "nested panels within collapsed row",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{
						"id":    1,
						"title": "Row Panel",
						"type":  "row",
						"panels": []interface{}{
							map[string]interface{}{"id": 2, "title": "Nested Panel 1", "type": "stat"},
							map[string]interface{}{"id": 3, "title": "Nested Panel 2", "type": "graph"},
						},
					},
				},
			},
			expectedIDs:    []int{1, 2, 3},
			expectedTitles: []string{"Row Panel", "Nested Panel 1", "Nested Panel 2"},
		},
		{
			name: "panels inside rows (old row-based format)",
			input: map[string]interface{}{
				"rows": []interface{}{
					map[string]interface{}{
						"title": "Row 1",
						"panels": []interface{}{
							map[string]interface{}{"id": 6, "title": "Row Panel 1", "type": "stat"},
							map[string]interface{}{"id": 7, "title": "Row Panel 2", "type": "graph"},
						},
					},
					map[string]interface{}{
						"title": "Row 2",
						"panels": []interface{}{
							map[string]interface{}{"id": 8, "title": "Row Panel 3", "type": "table"},
						},
					},
				},
			},
			expectedIDs:    []int{6, 7, 8},
			expectedTitles: []string{"Row Panel 1", "Row Panel 2", "Row Panel 3"},
		},
		{
			name: "ID collision scenario: top-level and row panels",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"id": 1, "title": "Top Level Panel", "type": "text"},
				},
				"rows": []interface{}{
					map[string]interface{}{
						"title": "Row with high ID panels",
						"panels": []interface{}{
							map[string]interface{}{"id": 6, "title": "Row Panel 1", "type": "stat"},
							map[string]interface{}{"id": 7, "title": "Row Panel 2", "type": "stat"},
						},
					},
				},
			},
			expectedIDs:    []int{1, 6, 7},
			expectedTitles: []string{"Top Level Panel", "Row Panel 1", "Row Panel 2"},
		},
		{
			name: "all panel sources combined",
			input: map[string]interface{}{
				"panels": []interface{}{
					map[string]interface{}{"id": 1, "title": "Top Level Panel", "type": "text"},
					map[string]interface{}{
						"id":    2,
						"title": "Collapsed Row",
						"type":  "row",
						"panels": []interface{}{
							map[string]interface{}{"id": 3, "title": "Nested Panel", "type": "stat"},
						},
					},
				},
				"rows": []interface{}{
					map[string]interface{}{
						"title": "Old Format Row",
						"panels": []interface{}{
							map[string]interface{}{"id": 10, "title": "Old Row Panel", "type": "graph"},
						},
					},
				},
			},
			expectedIDs:    []int{1, 2, 3, 10},
			expectedTitles: []string{"Top Level Panel", "Collapsed Row", "Nested Panel", "Old Row Panel"},
		},
		{
			name:           "empty dashboard",
			input:          map[string]interface{}{},
			expectedIDs:    []int{},
			expectedTitles: []string{},
		},
		{
			name: "rows with empty panels array",
			input: map[string]interface{}{
				"rows": []interface{}{
					map[string]interface{}{
						"title":  "Empty Row",
						"panels": []interface{}{},
					},
				},
			},
			expectedIDs:    []int{},
			expectedTitles: []string{},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			panels := getPanels(tt.input)

			if len(panels) != len(tt.expectedIDs) {
				t.Errorf("Expected %d panels, got %d", len(tt.expectedIDs), len(panels))
				return
			}

			for i, panel := range panels {
				if id, ok := panel["id"].(int); ok {
					if id != tt.expectedIDs[i] {
						t.Errorf("Panel %d: expected ID %d, got %d", i, tt.expectedIDs[i], id)
					}
				} else if len(tt.expectedIDs) > 0 {
					t.Errorf("Panel %d: missing or invalid ID", i)
				}

				if title, ok := panel["title"].(string); ok {
					if title != tt.expectedTitles[i] {
						t.Errorf("Panel %d: expected title %q, got %q", i, tt.expectedTitles[i], title)
					}
				} else if len(tt.expectedTitles) > 0 {
					t.Errorf("Panel %d: missing or invalid title", i)
				}
			}
		})
	}
}
