package handlers

import (
	"net/http"

	"github.com/breakpilot/consent-service/internal/middleware"
	"github.com/breakpilot/consent-service/internal/models"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// ========================================
// ADMIN — Communications & Status
// ========================================

// AdminGetDSRCommunications returns communications for a DSR
func (h *DSRHandler) AdminGetDSRCommunications(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	dsrID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request ID"})
		return
	}

	comms, err := h.dsrService.GetCommunications(c.Request.Context(), dsrID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch communications"})
		return
	}

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

// AdminSendDSRCommunication sends a communication for a DSR
func (h *DSRHandler) AdminSendDSRCommunication(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	dsrID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request ID"})
		return
	}

	userID, _ := middleware.GetUserID(c)

	var req models.SendDSRCommunicationRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	err = h.dsrService.SendCommunication(c.Request.Context(), dsrID, req, userID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Kommunikation wurde gesendet"})
}

// AdminUpdateDSRStatus updates the status of a DSR
func (h *DSRHandler) AdminUpdateDSRStatus(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	dsrID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request ID"})
		return
	}

	userID, _ := middleware.GetUserID(c)

	var req struct {
		Status  string `json:"status" binding:"required"`
		Comment string `json:"comment"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	err = h.dsrService.UpdateStatus(c.Request.Context(), dsrID, models.DSRStatus(req.Status), req.Comment, &userID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Status wurde aktualisiert"})
}

// ========================================
// EXCEPTION CHECKS (Art. 17)
// ========================================

// AdminGetExceptionChecks returns exception checks for an erasure DSR
func (h *DSRHandler) AdminGetExceptionChecks(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	dsrID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request ID"})
		return
	}

	checks, err := h.dsrService.GetExceptionChecks(c.Request.Context(), dsrID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch exception checks"})
		return
	}

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

// AdminInitExceptionChecks initializes exception checks for an erasure DSR
func (h *DSRHandler) AdminInitExceptionChecks(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	dsrID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request ID"})
		return
	}

	err = h.dsrService.InitErasureExceptionChecks(c.Request.Context(), dsrID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to initialize exception checks"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Ausnahmeprüfungen wurden initialisiert"})
}

// AdminUpdateExceptionCheck updates a single exception check
func (h *DSRHandler) AdminUpdateExceptionCheck(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	checkID, err := uuid.Parse(c.Param("checkId"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid check ID"})
		return
	}

	userID, _ := middleware.GetUserID(c)

	var req struct {
		Applies bool    `json:"applies"`
		Notes   *string `json:"notes"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	err = h.dsrService.UpdateExceptionCheck(c.Request.Context(), checkID, req.Applies, req.Notes, userID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update exception check"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Ausnahmeprüfung wurde aktualisiert"})
}

// ========================================
// DEADLINE PROCESSING
// ========================================

// ProcessDeadlines triggers deadline checking (called by scheduler)
func (h *DSRHandler) ProcessDeadlines(c *gin.Context) {
	err := h.dsrService.ProcessDeadlines(c.Request.Context())
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to process deadlines"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Deadline processing completed"})
}
