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"
)

// ============================================================================
// Monitoring
// ============================================================================

// CreateMonitoringEvent handles POST /projects/:id/monitoring
// Creates a new post-market monitoring event.
func (h *IACEHandler) CreateMonitoringEvent(c *gin.Context) {
	projectID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
		return
	}

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

	// Override project ID from URL path
	req.ProjectID = projectID

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

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

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

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

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

	if events == nil {
		events = []iace.MonitoringEvent{}
	}

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

// UpdateMonitoringEvent handles PUT /projects/:id/monitoring/:eid
// Updates a monitoring event with the provided fields.
func (h *IACEHandler) UpdateMonitoringEvent(c *gin.Context) {
	_, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
		return
	}

	eventID, err := uuid.Parse(c.Param("eid"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid monitoring event ID"})
		return
	}

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

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

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

// GetAuditTrail handles GET /projects/:id/audit-trail
// Returns all audit trail entries for a project, newest first.
func (h *IACEHandler) GetAuditTrail(c *gin.Context) {
	projectID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
		return
	}

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

	if entries == nil {
		entries = []iace.AuditTrailEntry{}
	}

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