package handlers

import (
	"encoding/json"
	"net/http"

	"github.com/breakpilot/ai-compliance-sdk/internal/iace"
	"github.com/breakpilot/ai-compliance-sdk/internal/rbac"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// ============================================================================
// Mitigations
// ============================================================================

// ListProjectMitigations handles GET /projects/:id/mitigations
// Returns all mitigations for all hazards in a project.
func (h *IACEHandler) ListProjectMitigations(c *gin.Context) {
	projectID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
		return
	}

	mitigations, err := h.store.ListMitigationsByProject(c.Request.Context(), projectID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	if mitigations == nil {
		mitigations = []iace.Mitigation{}
	}

	c.JSON(http.StatusOK, gin.H{
		"mitigations": mitigations,
		"total":       len(mitigations),
	})
}

// CreateMitigation handles POST /projects/:id/hazards/:hid/mitigations
// Creates a new mitigation measure for a hazard.
func (h *IACEHandler) CreateMitigation(c *gin.Context) {
	projectID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
		return
	}

	hazardID, err := uuid.Parse(c.Param("hid"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid hazard ID"})
		return
	}

	var req iace.CreateMitigationRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Override hazard ID from URL path
	req.HazardID = hazardID

	mitigation, err := h.store.CreateMitigation(c.Request.Context(), req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Update hazard status to mitigated
	h.store.UpdateHazard(c.Request.Context(), hazardID, map[string]interface{}{
		"status": string(iace.HazardStatusMitigated),
	})

	// Audit trail
	userID := rbac.GetUserID(c)
	newVals, _ := json.Marshal(mitigation)
	h.store.AddAuditEntry(
		c.Request.Context(), projectID, "mitigation", mitigation.ID,
		iace.AuditActionCreate, userID.String(), nil, newVals,
	)

	c.JSON(http.StatusCreated, gin.H{"mitigation": mitigation})
}

// UpdateMitigation handles PUT /mitigations/:mid
// Updates a mitigation measure with the provided fields.
func (h *IACEHandler) UpdateMitigation(c *gin.Context) {
	mitigationID, err := uuid.Parse(c.Param("mid"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid mitigation ID"})
		return
	}

	var updates map[string]interface{}
	if err := c.ShouldBindJSON(&updates); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	mitigation, err := h.store.UpdateMitigation(c.Request.Context(), mitigationID, updates)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if mitigation == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "mitigation not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"mitigation": mitigation})
}

// DeleteMitigation handles DELETE /projects/:id/mitigations/:mid
// Deletes a mitigation by ID.
func (h *IACEHandler) DeleteMitigation(c *gin.Context) {
	mitigationID, err := uuid.Parse(c.Param("mid"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid mitigation ID"})
		return
	}

	if err := h.store.DeleteMitigation(c.Request.Context(), mitigationID); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "mitigation deleted"})
}

// VerifyMitigation handles POST /mitigations/:mid/verify
// Marks a mitigation as verified with a verification result.
func (h *IACEHandler) VerifyMitigation(c *gin.Context) {
	mitigationID, err := uuid.Parse(c.Param("mid"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid mitigation ID"})
		return
	}

	var req struct {
		VerificationResult string `json:"verification_result" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	userID := rbac.GetUserID(c)

	if err := h.store.VerifyMitigation(
		c.Request.Context(), mitigationID, req.VerificationResult, userID.String(),
	); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "mitigation verified"})
}
