package maximizer

import (
	"testing"

	"github.com/breakpilot/ai-compliance-sdk/internal/ucca"
)

func TestGetValueSetValueRoundtrip(t *testing.T) {
	config := DimensionConfig{
		AutomationLevel:      AutoFull,
		DecisionBinding:      BindingFullyBinding,
		DecisionImpact:       ImpactHigh,
		Domain:               DomainHR,
		DataType:             DataPersonal,
		HumanInLoop:          HILNone,
		Explainability:       ExplainNone,
		RiskClassification:   RiskHigh,
		LegalBasis:           LegalContract,
		TransparencyRequired: true,
		LoggingRequired:      false,
		ModelType:            ModelBlackboxLLM,
		DeploymentScope:      ScopeExternal,
	}

	for _, dim := range allDimensions {
		val := config.GetValue(dim)
		if val == "" {
			t.Errorf("GetValue(%q) returned empty", dim)
		}
		clone := DimensionConfig{}
		ok := clone.SetValue(dim, val)
		if !ok {
			t.Errorf("SetValue(%q, %q) returned false", dim, val)
		}
		if clone.GetValue(dim) != val {
			t.Errorf("SetValue roundtrip failed for %q: got %q, want %q", dim, clone.GetValue(dim), val)
		}
	}
}

func TestGetValueUnknownDimension(t *testing.T) {
	config := DimensionConfig{}
	if v := config.GetValue("nonexistent"); v != "" {
		t.Errorf("expected empty for unknown dimension, got %q", v)
	}
	if ok := config.SetValue("nonexistent", "x"); ok {
		t.Error("expected false for unknown dimension")
	}
}

func TestDiffIdentical(t *testing.T) {
	config := DimensionConfig{
		AutomationLevel: AutoAssistive,
		DecisionImpact:  ImpactLow,
		Domain:          DomainGeneral,
	}
	deltas := config.Diff(&config)
	if len(deltas) != 0 {
		t.Errorf("expected 0 deltas for identical configs, got %d", len(deltas))
	}
}

func TestDiffDetectsChanges(t *testing.T) {
	a := DimensionConfig{
		AutomationLevel: AutoFull,
		HumanInLoop:     HILNone,
		DecisionBinding: BindingFullyBinding,
	}
	b := DimensionConfig{
		AutomationLevel: AutoAssistive,
		HumanInLoop:     HILRequired,
		DecisionBinding: BindingHumanReview,
	}
	deltas := a.Diff(&b)

	changed := make(map[string]bool)
	for _, d := range deltas {
		changed[d.Dimension] = true
	}
	for _, dim := range []string{"automation_level", "human_in_loop", "decision_binding"} {
		if !changed[dim] {
			t.Errorf("expected %q in deltas", dim)
		}
	}
}

func TestClone(t *testing.T) {
	orig := DimensionConfig{
		AutomationLevel: AutoFull,
		Domain:          DomainHR,
	}
	clone := orig.Clone()
	clone.AutomationLevel = AutoAssistive
	if orig.AutomationLevel != AutoFull {
		t.Error("clone modified original")
	}
}

func TestMapIntakeToDimensions(t *testing.T) {
	intake := &ucca.UseCaseIntake{
		Domain:     "hr",
		Automation: ucca.AutomationFullyAutomated,
		DataTypes: ucca.DataTypes{
			PersonalData: true,
			Article9Data: true,
		},
		Purpose: ucca.Purpose{
			DecisionMaking: true,
		},
		Outputs: ucca.Outputs{
			LegalEffects: true,
		},
		ModelUsage: ucca.ModelUsage{
			Training: true,
		},
	}

	config := MapIntakeToDimensions(intake)

	tests := []struct {
		dimension string
		expected  string
	}{
		{"automation_level", "full"},
		{"domain", "hr"},
		{"data_type", "sensitive"},
		{"decision_impact", "high"},
		{"model_type", "blackbox_llm"},
		{"human_in_loop", "none"},
		{"decision_binding", "fully_binding"},
	}
	for _, tc := range tests {
		got := config.GetValue(tc.dimension)
		if got != tc.expected {
			t.Errorf("MapIntakeToDimensions: %s = %q, want %q", tc.dimension, got, tc.expected)
		}
	}
}

func TestMapIntakeToDimensionsBiometricWins(t *testing.T) {
	intake := &ucca.UseCaseIntake{
		DataTypes: ucca.DataTypes{
			PersonalData:  true,
			Article9Data:  true,
			BiometricData: true,
		},
	}
	config := MapIntakeToDimensions(intake)
	if config.DataType != DataBiometric {
		t.Errorf("expected biometric (highest sensitivity), got %s", config.DataType)
	}
}

func TestMapDimensionsToIntakePreservesOriginal(t *testing.T) {
	original := &ucca.UseCaseIntake{
		UseCaseText: "Test use case",
		Domain:      "hr",
		Title:       "My Assessment",
		Automation:  ucca.AutomationFullyAutomated,
		DataTypes: ucca.DataTypes{
			PersonalData: true,
		},
		Hosting: ucca.Hosting{
			Region: "eu",
		},
	}

	config := &DimensionConfig{
		AutomationLevel: AutoAssistive,
		DataType:        DataPersonal,
		Domain:          DomainHR,
	}

	result := MapDimensionsToIntake(config, original)

	if result.UseCaseText != "Test use case" {
		t.Error("MapDimensionsToIntake did not preserve UseCaseText")
	}
	if result.Title != "My Assessment" {
		t.Error("MapDimensionsToIntake did not preserve Title")
	}
	if result.Hosting.Region != "eu" {
		t.Error("MapDimensionsToIntake did not preserve Hosting")
	}
	if result.Automation != ucca.AutomationAssistive {
		t.Errorf("expected assistive automation, got %s", result.Automation)
	}
}

func TestAllValuesComplete(t *testing.T) {
	for _, dim := range allDimensions {
		vals, ok := AllValues[dim]
		if !ok {
			t.Errorf("AllValues missing dimension %q", dim)
		}
		if len(vals) == 0 {
			t.Errorf("AllValues[%q] is empty", dim)
		}
	}
}
