package usecase

import (
	"testing"

	"github.com/google/uuid"
)

func TestScore_AllPassed(t *testing.T) {
	audit := &Audit{
		ID: uuid.New(),
		Questions: []Question{
			{ID: "Q1", Severity: "HIGH", Regulation: "DSGVO"},
			{ID: "Q2", Severity: "MEDIUM", Regulation: "NIS2"},
			{ID: "Q3", Severity: "LOW", Regulation: "DSGVO"},
		},
	}
	answers := []Answer{
		{QuestionID: "Q1", Value: true, Status: AnswerStatusAnswered},
		{QuestionID: "Q2", Value: true, Status: AnswerStatusAnswered},
		{QuestionID: "Q3", Value: true, Status: AnswerStatusAnswered},
	}

	result := Score(audit, answers)

	if result.ComplianceScore != 100 {
		t.Errorf("Expected 100%% score, got %.1f%%", result.ComplianceScore)
	}
	if result.Passed != 3 {
		t.Errorf("Expected 3 passed, got %d", result.Passed)
	}
	if result.Failed != 0 {
		t.Errorf("Expected 0 failed, got %d", result.Failed)
	}
}

func TestScore_MixedResults(t *testing.T) {
	audit := &Audit{
		ID: uuid.New(),
		Questions: []Question{
			{ID: "Q1", Severity: "HIGH", Regulation: "DSGVO"},
			{ID: "Q2", Severity: "HIGH", Regulation: "DSGVO"},
			{ID: "Q3", Severity: "MEDIUM", Regulation: "NIS2"},
			{ID: "Q4", Severity: "LOW", Regulation: "NIS2"},
		},
	}
	answers := []Answer{
		{QuestionID: "Q1", Value: true, Status: AnswerStatusAnswered},
		{QuestionID: "Q2", Value: false, Status: AnswerStatusAnswered},
		{QuestionID: "Q3", Value: true, Status: AnswerStatusAnswered},
		{QuestionID: "Q4", Value: false, Status: AnswerStatusAnswered},
	}

	result := Score(audit, answers)

	if result.ComplianceScore != 50 {
		t.Errorf("Expected 50%% score, got %.1f%%", result.ComplianceScore)
	}
	if result.Passed != 2 {
		t.Errorf("Expected 2 passed, got %d", result.Passed)
	}
	if result.Failed != 2 {
		t.Errorf("Expected 2 failed, got %d", result.Failed)
	}

	// Check regulation breakdown
	dsgvo := result.ByRegulation["DSGVO"]
	if dsgvo.Total != 2 || dsgvo.Passed != 1 {
		t.Errorf("DSGVO: expected 1/2, got %d/%d", dsgvo.Passed, dsgvo.Total)
	}

	nis2 := result.ByRegulation["NIS2"]
	if nis2.Total != 2 || nis2.Passed != 1 {
		t.Errorf("NIS2: expected 1/2, got %d/%d", nis2.Passed, nis2.Total)
	}
}

func TestScore_WithSkipped(t *testing.T) {
	audit := &Audit{
		ID: uuid.New(),
		Questions: []Question{
			{ID: "Q1", Severity: "HIGH"},
			{ID: "Q2", Severity: "MEDIUM"},
		},
	}
	answers := []Answer{
		{QuestionID: "Q1", Value: true, Status: AnswerStatusAnswered},
		{QuestionID: "Q2", Value: nil, Status: AnswerStatusSkipped},
	}

	result := Score(audit, answers)

	if result.Skipped != 1 {
		t.Errorf("Expected 1 skipped, got %d", result.Skipped)
	}
	if result.ComplianceScore != 100 {
		t.Errorf("Expected 100%% (1 passed / 1 answerable), got %.1f%%", result.ComplianceScore)
	}
}

func TestScore_NoAnswers(t *testing.T) {
	audit := &Audit{
		ID: uuid.New(),
		Questions: []Question{
			{ID: "Q1", Severity: "HIGH"},
		},
	}

	result := Score(audit, nil)

	if result.ComplianceScore != 0 {
		t.Errorf("Expected 0%% score, got %.1f%%", result.ComplianceScore)
	}
	if result.Answered != 0 {
		t.Errorf("Expected 0 answered, got %d", result.Answered)
	}
}

func TestScore_BySeverity(t *testing.T) {
	audit := &Audit{
		ID: uuid.New(),
		Questions: []Question{
			{ID: "Q1", Severity: "HIGH"},
			{ID: "Q2", Severity: "HIGH"},
			{ID: "Q3", Severity: "MEDIUM"},
		},
	}
	answers := []Answer{
		{QuestionID: "Q1", Value: true, Status: AnswerStatusAnswered},
		{QuestionID: "Q2", Value: false, Status: AnswerStatusAnswered},
		{QuestionID: "Q3", Value: true, Status: AnswerStatusAnswered},
	}

	result := Score(audit, answers)

	high := result.BySeverity["HIGH"]
	if high.Total != 2 || high.Passed != 1 || high.Failed != 1 {
		t.Errorf("HIGH: expected 1/2 (1 fail), got %d/%d (%d fail)",
			high.Passed, high.Total, high.Failed)
	}

	med := result.BySeverity["MEDIUM"]
	if med.Total != 1 || med.Passed != 1 {
		t.Errorf("MEDIUM: expected 1/1, got %d/%d", med.Passed, med.Total)
	}
}

func TestIsPassed_BoolValues(t *testing.T) {
	tests := []struct {
		name   string
		value  interface{}
		expect bool
	}{
		{"true bool", true, true},
		{"false bool", false, false},
		{"yes string", "yes", true},
		{"no string", "no", false},
		{"ja string", "ja", true},
		{"positive float", float64(1), true},
		{"zero float", float64(0), false},
		{"nil value", nil, false},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			a := Answer{Value: tt.value, Status: AnswerStatusAnswered}
			got := isPassed(a)
			if got != tt.expect {
				t.Errorf("isPassed(%v) = %v, want %v", tt.value, got, tt.expect)
			}
		})
	}
}
