package api

import (
	"net/http"

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

// Checkpoint represents a checkpoint definition
type Checkpoint struct {
	ID             string   `json:"id"`
	Step           string   `json:"step"`
	Name           string   `json:"name"`
	Type           string   `json:"type"`
	BlocksProgress bool     `json:"blocksProgress"`
	RequiresReview string   `json:"requiresReview"`
	AutoValidate   bool     `json:"autoValidate"`
	Description    string   `json:"description"`
}

// CheckpointHandler handles checkpoint-related requests
type CheckpointHandler struct {
	checkpoints map[string]Checkpoint
}

// NewCheckpointHandler creates a new checkpoint handler
func NewCheckpointHandler() *CheckpointHandler {
	return &CheckpointHandler{
		checkpoints: initCheckpoints(),
	}
}

func initCheckpoints() map[string]Checkpoint {
	return map[string]Checkpoint{
		"CP-UC": {
			ID:             "CP-UC",
			Step:           "use-case-workshop",
			Name:           "Use Case Erfassung",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Mindestens ein Use Case muss erfasst sein",
		},
		"CP-SCAN": {
			ID:             "CP-SCAN",
			Step:           "screening",
			Name:           "System Screening",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "SBOM und Security Scan müssen abgeschlossen sein",
		},
		"CP-MOD": {
			ID:             "CP-MOD",
			Step:           "modules",
			Name:           "Modul-Zuweisung",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Mindestens ein Compliance-Modul muss zugewiesen sein",
		},
		"CP-REQ": {
			ID:             "CP-REQ",
			Step:           "requirements",
			Name:           "Anforderungen",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Anforderungen müssen aus Regulierungen abgeleitet sein",
		},
		"CP-CTRL": {
			ID:             "CP-CTRL",
			Step:           "controls",
			Name:           "Controls",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Controls müssen den Anforderungen zugeordnet sein",
		},
		"CP-EVI": {
			ID:             "CP-EVI",
			Step:           "evidence",
			Name:           "Nachweise",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Nachweise für Controls müssen dokumentiert sein",
		},
		"CP-CHK": {
			ID:             "CP-CHK",
			Step:           "audit-checklist",
			Name:           "Audit Checklist",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Prüfliste muss generiert und überprüft sein",
		},
		"CP-RISK": {
			ID:             "CP-RISK",
			Step:           "risks",
			Name:           "Risikobewertung",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Kritische Risiken müssen Mitigationsmaßnahmen haben",
		},
		"CP-AI": {
			ID:             "CP-AI",
			Step:           "ai-act",
			Name:           "AI Act Klassifizierung",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "LEGAL",
			AutoValidate:   false,
			Description:    "KI-System muss klassifiziert sein",
		},
		"CP-OBL": {
			ID:             "CP-OBL",
			Step:           "obligations",
			Name:           "Pflichtenübersicht",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Rechtliche Pflichten müssen identifiziert sein",
		},
		"CP-DSFA": {
			ID:             "CP-DSFA",
			Step:           "dsfa",
			Name:           "DSFA",
			Type:           "RECOMMENDED",
			BlocksProgress: false,
			RequiresReview: "DSB",
			AutoValidate:   false,
			Description:    "Datenschutz-Folgenabschätzung muss erstellt und genehmigt sein",
		},
		"CP-TOM": {
			ID:             "CP-TOM",
			Step:           "tom",
			Name:           "TOMs",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "NONE",
			AutoValidate:   true,
			Description:    "Technische und organisatorische Maßnahmen müssen definiert sein",
		},
		"CP-VVT": {
			ID:             "CP-VVT",
			Step:           "vvt",
			Name:           "Verarbeitungsverzeichnis",
			Type:           "REQUIRED",
			BlocksProgress: true,
			RequiresReview: "DSB",
			AutoValidate:   false,
			Description:    "Verarbeitungsverzeichnis muss vollständig sein",
		},
	}
}

// GetAll returns all checkpoint definitions
func (h *CheckpointHandler) GetAll(c *gin.Context) {
	tenantID := c.Query("tenantId")

	checkpointList := make([]Checkpoint, 0, len(h.checkpoints))
	for _, cp := range h.checkpoints {
		checkpointList = append(checkpointList, cp)
	}

	SuccessResponse(c, gin.H{
		"tenantId":    tenantID,
		"checkpoints": checkpointList,
	})
}

// Validate validates a specific checkpoint
func (h *CheckpointHandler) Validate(c *gin.Context) {
	var req struct {
		TenantID     string                 `json:"tenantId" binding:"required"`
		CheckpointID string                 `json:"checkpointId" binding:"required"`
		Data         map[string]interface{} `json:"data"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		ErrorResponse(c, http.StatusBadRequest, err.Error(), "INVALID_REQUEST")
		return
	}

	checkpoint, ok := h.checkpoints[req.CheckpointID]
	if !ok {
		ErrorResponse(c, http.StatusNotFound, "Checkpoint not found", "CHECKPOINT_NOT_FOUND")
		return
	}

	// Perform validation based on checkpoint ID
	result := h.validateCheckpoint(checkpoint, req.Data)

	SuccessResponse(c, result)
}

func (h *CheckpointHandler) validateCheckpoint(checkpoint Checkpoint, data map[string]interface{}) CheckpointResult {
	result := CheckpointResult{
		CheckpointID: checkpoint.ID,
		Passed:       true,
		ValidatedAt:  now(),
		ValidatedBy:  "SYSTEM",
		Errors:       []ValidationError{},
		Warnings:     []ValidationError{},
	}

	// Validation logic based on checkpoint
	switch checkpoint.ID {
	case "CP-UC":
		useCases, _ := data["useCases"].([]interface{})
		if len(useCases) == 0 {
			result.Passed = false
			result.Errors = append(result.Errors, ValidationError{
				RuleID:   "uc-min-count",
				Field:    "useCases",
				Message:  "Mindestens ein Use Case muss erstellt werden",
				Severity: "ERROR",
			})
		}

	case "CP-SCAN":
		screening, _ := data["screening"].(map[string]interface{})
		if screening == nil || screening["status"] != "COMPLETED" {
			result.Passed = false
			result.Errors = append(result.Errors, ValidationError{
				RuleID:   "scan-complete",
				Field:    "screening",
				Message:  "Security Scan muss abgeschlossen sein",
				Severity: "ERROR",
			})
		}

	case "CP-MOD":
		modules, _ := data["modules"].([]interface{})
		if len(modules) == 0 {
			result.Passed = false
			result.Errors = append(result.Errors, ValidationError{
				RuleID:   "mod-min-count",
				Field:    "modules",
				Message:  "Mindestens ein Modul muss zugewiesen werden",
				Severity: "ERROR",
			})
		}

	case "CP-RISK":
		risks, _ := data["risks"].([]interface{})
		criticalUnmitigated := 0
		for _, r := range risks {
			risk, ok := r.(map[string]interface{})
			if !ok {
				continue
			}
			severity, _ := risk["severity"].(string)
			if severity == "CRITICAL" || severity == "HIGH" {
				mitigations, _ := risk["mitigation"].([]interface{})
				if len(mitigations) == 0 {
					criticalUnmitigated++
				}
			}
		}
		if criticalUnmitigated > 0 {
			result.Passed = false
			result.Errors = append(result.Errors, ValidationError{
				RuleID:   "critical-risks-mitigated",
				Field:    "risks",
				Message:  "Kritische Risiken ohne Mitigationsmaßnahmen gefunden",
				Severity: "ERROR",
			})
		}

	case "CP-DSFA":
		dsfa, _ := data["dsfa"].(map[string]interface{})
		if dsfa == nil {
			result.Passed = false
			result.Errors = append(result.Errors, ValidationError{
				RuleID:   "dsfa-exists",
				Field:    "dsfa",
				Message:  "DSFA muss erstellt werden",
				Severity: "ERROR",
			})
		} else if dsfa["status"] != "APPROVED" {
			result.Warnings = append(result.Warnings, ValidationError{
				RuleID:   "dsfa-approved",
				Field:    "dsfa",
				Message:  "DSFA sollte vom DSB genehmigt werden",
				Severity: "WARNING",
			})
		}

	case "CP-TOM":
		toms, _ := data["toms"].([]interface{})
		if len(toms) == 0 {
			result.Passed = false
			result.Errors = append(result.Errors, ValidationError{
				RuleID:   "tom-min-count",
				Field:    "toms",
				Message:  "Mindestens eine TOM muss definiert werden",
				Severity: "ERROR",
			})
		}

	case "CP-VVT":
		vvt, _ := data["vvt"].([]interface{})
		if len(vvt) == 0 {
			result.Passed = false
			result.Errors = append(result.Errors, ValidationError{
				RuleID:   "vvt-min-count",
				Field:    "vvt",
				Message:  "Mindestens eine Verarbeitungstätigkeit muss dokumentiert werden",
				Severity: "ERROR",
			})
		}
	}

	return result
}
