package handlers

import (
	"net/http"
	"testing"

	"github.com/gin-gonic/gin"
)

// newTestContext, parseResponse, and gin.SetMode are defined in iace_handler_test.go

// ============================================================================
// Module Endpoint Tests
// ============================================================================

func TestGetModule_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/modules/not-a-uuid", nil, nil, gin.Params{{Key: "id", Value: "not-a-uuid"}})
	h.GetModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGetModule_EmptyID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/modules/", nil, nil, gin.Params{{Key: "id", Value: ""}})
	h.GetModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestCreateModule_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/modules", nil, nil, nil)
	h.CreateModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestCreateModule_MissingTitle_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{"module_code": "T01", "regulation_area": "dsgvo", "frequency_type": "annual"}
	w, c := newTestContext("POST", "/modules", body, nil, nil)
	h.CreateModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestCreateModule_MissingModuleCode_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{"title": "Test", "regulation_area": "dsgvo", "frequency_type": "annual"}
	w, c := newTestContext("POST", "/modules", body, nil, nil)
	h.CreateModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestCreateModule_MissingRegulationArea_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{"module_code": "T01", "title": "Test", "frequency_type": "annual"}
	w, c := newTestContext("POST", "/modules", body, nil, nil)
	h.CreateModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestUpdateModule_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("PUT", "/modules/bad", map[string]interface{}{"title": "x"}, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.UpdateModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestDeleteModule_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("DELETE", "/modules/bad", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.DeleteModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestDeleteModule_EmptyID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("DELETE", "/modules/", nil, nil, gin.Params{{Key: "id", Value: ""}})
	h.DeleteModule(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Matrix Endpoint Tests
// ============================================================================

func TestSetMatrixEntry_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/matrix", nil, nil, nil)
	h.SetMatrixEntry(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestSetMatrixEntry_MissingRoleCode_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{"module_id": "00000000-0000-0000-0000-000000000001"}
	w, c := newTestContext("POST", "/matrix", body, nil, nil)
	h.SetMatrixEntry(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestDeleteMatrixEntry_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("DELETE", "/matrix/R1/bad", nil, nil, gin.Params{
		{Key: "role", Value: "R1"},
		{Key: "moduleId", Value: "bad"},
	})
	h.DeleteMatrixEntry(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Assignment Endpoint Tests
// ============================================================================

func TestGetAssignment_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/assignments/bad", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.GetAssignment(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestStartAssignment_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/assignments/bad/start", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.StartAssignment(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestUpdateAssignmentProgress_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/assignments/bad/progress", map[string]interface{}{"progress": 50}, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.UpdateAssignmentProgress(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestUpdateAssignmentProgress_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/assignments/00000000-0000-0000-0000-000000000001/progress", nil, nil,
		gin.Params{{Key: "id", Value: "00000000-0000-0000-0000-000000000001"}})
	h.UpdateAssignmentProgress(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestCompleteAssignment_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/assignments/bad/complete", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.CompleteAssignment(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestComputeAssignments_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/assignments/compute", nil, nil, nil)
	h.ComputeAssignments(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestComputeAssignments_MissingUserID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{"user_name": "Test", "user_email": "test@test.de", "roles": []string{"R1"}}
	w, c := newTestContext("POST", "/assignments/compute", body, nil, nil)
	h.ComputeAssignments(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Quiz Endpoint Tests
// ============================================================================

func TestGetQuiz_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/quiz/bad", nil, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.GetQuiz(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestSubmitQuiz_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/quiz/bad/submit", map[string]interface{}{}, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.SubmitQuiz(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestSubmitQuiz_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/quiz/00000000-0000-0000-0000-000000000001/submit", nil, nil,
		gin.Params{{Key: "moduleId", Value: "00000000-0000-0000-0000-000000000001"}})
	h.SubmitQuiz(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGetQuizAttempts_InvalidAssignmentID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/quiz/attempts/bad", nil, nil, gin.Params{{Key: "assignmentId", Value: "bad"}})
	h.GetQuizAttempts(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Content Endpoint Tests
// ============================================================================

func TestGetContent_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/content/bad", nil, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.GetContent(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestPublishContent_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/content/bad/publish", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.PublishContent(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGenerateContent_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/content/generate", nil, nil, nil)
	h.GenerateContent(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGenerateQuiz_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/content/generate-quiz", nil, nil, nil)
	h.GenerateQuiz(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Media Endpoint Tests
// ============================================================================

func TestGetModuleMedia_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/media/module/bad", nil, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.GetModuleMedia(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGetMediaURL_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/media/bad/url", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.GetMediaURL(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestPublishMedia_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/media/bad/publish", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.PublishMedia(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestStreamMedia_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/media/bad/stream", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.StreamMedia(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGenerateAudio_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/content/bad/generate-audio", nil, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.GenerateAudio(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGenerateVideo_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/content/bad/generate-video", nil, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.GenerateVideo(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestPreviewVideoScript_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/content/bad/preview-script", nil, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.PreviewVideoScript(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Certificate Endpoint Tests
// ============================================================================

func TestGenerateCertificate_InvalidAssignmentID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/certificates/generate/bad", nil, nil, gin.Params{{Key: "assignmentId", Value: "bad"}})
	h.GenerateCertificate(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestDownloadCertificatePDF_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/certificates/bad/pdf", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.DownloadCertificatePDF(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestVerifyCertificate_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/certificates/bad/verify", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.VerifyCertificate(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestListCertificates_NilStore_Panics(t *testing.T) {
	// This tests that a nil store doesn't silently succeed
	defer func() {
		if r := recover(); r == nil {
			t.Error("Expected panic with nil store")
		}
	}()
	h := &TrainingHandlers{}
	_, c := newTestContext("GET", "/certificates", nil, nil, nil)
	h.ListCertificates(c)
}

// ============================================================================
// Interactive Video Endpoint Tests (User Journey: Admin generates video)
// ============================================================================

func TestGenerateInteractiveVideo_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/content/bad/generate-interactive", nil, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.GenerateInteractiveVideo(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
	resp := parseResponse(w)
	if resp["error"] == nil {
		t.Error("Response should contain 'error' key")
	}
}

func TestGenerateInteractiveVideo_EmptyModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/content//generate-interactive", nil, nil, gin.Params{{Key: "moduleId", Value: ""}})
	h.GenerateInteractiveVideo(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGetInteractiveManifest_InvalidModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/content/bad/interactive-manifest", nil, nil, gin.Params{{Key: "moduleId", Value: "bad"}})
	h.GetInteractiveManifest(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
	resp := parseResponse(w)
	if resp["error"] == nil {
		t.Error("Response should contain 'error' key")
	}
}

func TestGetInteractiveManifest_EmptyModuleID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/content//interactive-manifest", nil, nil, gin.Params{{Key: "moduleId", Value: ""}})
	h.GetInteractiveManifest(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Checkpoint Quiz Endpoint Tests (User Journey: Learner takes quiz)
// ============================================================================

func TestSubmitCheckpointQuiz_InvalidCheckpointID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{
		"assignment_id": "00000000-0000-0000-0000-000000000001",
		"answers":       []int{0, 1, 2},
	}
	w, c := newTestContext("POST", "/checkpoints/bad/submit", body, nil, gin.Params{{Key: "checkpointId", Value: "bad"}})
	h.SubmitCheckpointQuiz(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
	resp := parseResponse(w)
	if resp["error"] == nil {
		t.Error("Response should contain 'error' key")
	}
}

func TestSubmitCheckpointQuiz_EmptyCheckpointID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{
		"assignment_id": "00000000-0000-0000-0000-000000000001",
		"answers":       []int{0},
	}
	w, c := newTestContext("POST", "/checkpoints//submit", body, nil, gin.Params{{Key: "checkpointId", Value: ""}})
	h.SubmitCheckpointQuiz(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestSubmitCheckpointQuiz_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/checkpoints/00000000-0000-0000-0000-000000000001/submit", nil, nil,
		gin.Params{{Key: "checkpointId", Value: "00000000-0000-0000-0000-000000000001"}})
	h.SubmitCheckpointQuiz(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestSubmitCheckpointQuiz_InvalidAssignmentID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{
		"assignment_id": "not-a-uuid",
		"answers":       []int{0},
	}
	w, c := newTestContext("POST", "/checkpoints/00000000-0000-0000-0000-000000000001/submit", body, nil,
		gin.Params{{Key: "checkpointId", Value: "00000000-0000-0000-0000-000000000001"}})
	h.SubmitCheckpointQuiz(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestSubmitCheckpointQuiz_ValidIDs_NilStore_Panics(t *testing.T) {
	// When both IDs are valid, handler reaches store → panic with nil store
	defer func() {
		if r := recover(); r == nil {
			t.Error("Expected panic with nil store")
		}
	}()
	h := &TrainingHandlers{}
	body := map[string]interface{}{
		"assignment_id": "00000000-0000-0000-0000-000000000001",
		"answers":       []int{0},
	}
	_, c := newTestContext("POST", "/checkpoints/00000000-0000-0000-0000-000000000001/submit", body, nil,
		gin.Params{{Key: "checkpointId", Value: "00000000-0000-0000-0000-000000000001"}})
	h.SubmitCheckpointQuiz(c)
}

// ============================================================================
// Checkpoint Progress Endpoint Tests (User Journey: Learner views progress)
// ============================================================================

func TestGetCheckpointProgress_InvalidAssignmentID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/checkpoints/progress/bad", nil, nil, gin.Params{{Key: "assignmentId", Value: "bad"}})
	h.GetCheckpointProgress(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
	resp := parseResponse(w)
	if resp["error"] == nil {
		t.Error("Response should contain 'error' key")
	}
}

func TestGetCheckpointProgress_EmptyAssignmentID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/checkpoints/progress/", nil, nil, gin.Params{{Key: "assignmentId", Value: ""}})
	h.GetCheckpointProgress(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Interactive Video Error Format Tests (table-driven)
// ============================================================================

func TestInteractiveEndpoints_InvalidID_ResponseContainsErrorKey(t *testing.T) {
	tests := []struct {
		name    string
		method  string
		handler func(h *TrainingHandlers, c *gin.Context)
		params  gin.Params
	}{
		{"GenerateInteractiveVideo", "POST",
			func(h *TrainingHandlers, c *gin.Context) { h.GenerateInteractiveVideo(c) },
			gin.Params{{Key: "moduleId", Value: "x"}}},
		{"GetInteractiveManifest", "GET",
			func(h *TrainingHandlers, c *gin.Context) { h.GetInteractiveManifest(c) },
			gin.Params{{Key: "moduleId", Value: "x"}}},
		{"SubmitCheckpointQuiz", "POST",
			func(h *TrainingHandlers, c *gin.Context) { h.SubmitCheckpointQuiz(c) },
			gin.Params{{Key: "checkpointId", Value: "x"}}},
		{"GetCheckpointProgress", "GET",
			func(h *TrainingHandlers, c *gin.Context) { h.GetCheckpointProgress(c) },
			gin.Params{{Key: "assignmentId", Value: "x"}}},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			h := &TrainingHandlers{}
			w, c := newTestContext(tt.method, "/test", nil, nil, tt.params)
			tt.handler(h, c)
			if w.Code != http.StatusBadRequest {
				t.Errorf("%s: Expected 400, got %d", tt.name, w.Code)
			}
			resp := parseResponse(w)
			if resp["error"] == nil {
				t.Errorf("%s: response should contain 'error' key", tt.name)
			}
		})
	}
}

// ============================================================================
// Block Endpoint Tests
// ============================================================================

func TestGetBlockConfig_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/blocks/bad", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.GetBlockConfig(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestCreateBlockConfig_EmptyBody_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/blocks", nil, nil, nil)
	h.CreateBlockConfig(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestCreateBlockConfig_MissingName_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	body := map[string]interface{}{"regulation_area": "dsgvo", "module_code_prefix": "BLK"}
	w, c := newTestContext("POST", "/blocks", body, nil, nil)
	h.CreateBlockConfig(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestUpdateBlockConfig_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("PUT", "/blocks/bad", map[string]interface{}{"name": "x"}, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.UpdateBlockConfig(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestDeleteBlockConfig_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("DELETE", "/blocks/bad", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.DeleteBlockConfig(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestPreviewBlock_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/blocks/bad/preview", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.PreviewBlock(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGenerateBlock_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("POST", "/blocks/bad/generate", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.GenerateBlock(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

func TestGetBlockControls_InvalidID_Returns400(t *testing.T) {
	h := &TrainingHandlers{}
	w, c := newTestContext("GET", "/blocks/bad/controls", nil, nil, gin.Params{{Key: "id", Value: "bad"}})
	h.GetBlockControls(c)
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected 400, got %d", w.Code)
	}
}

// ============================================================================
// Response Error Format Tests
// ============================================================================

func TestInvalidID_ResponseContainsErrorKey(t *testing.T) {
	tests := []struct {
		name    string
		method  string
		handler func(h *TrainingHandlers, c *gin.Context)
		params  gin.Params
	}{
		{"GetModule", "GET", func(h *TrainingHandlers, c *gin.Context) { h.GetModule(c) }, gin.Params{{Key: "id", Value: "x"}}},
		{"DeleteModule", "DELETE", func(h *TrainingHandlers, c *gin.Context) { h.DeleteModule(c) }, gin.Params{{Key: "id", Value: "x"}}},
		{"StreamMedia", "GET", func(h *TrainingHandlers, c *gin.Context) { h.StreamMedia(c) }, gin.Params{{Key: "id", Value: "x"}}},
		{"GenerateCertificate", "POST", func(h *TrainingHandlers, c *gin.Context) { h.GenerateCertificate(c) }, gin.Params{{Key: "assignmentId", Value: "x"}}},
		{"DownloadCertificatePDF", "GET", func(h *TrainingHandlers, c *gin.Context) { h.DownloadCertificatePDF(c) }, gin.Params{{Key: "id", Value: "x"}}},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			h := &TrainingHandlers{}
			w, c := newTestContext(tt.method, "/test", nil, nil, tt.params)
			tt.handler(h, c)
			resp := parseResponse(w)
			if resp["error"] == nil {
				t.Errorf("%s: response should contain 'error' key", tt.name)
			}
		})
	}
}
