package handlers

import (
	"context"
	"net/http"
	"strconv"
	"time"

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

// DSRHandler handles Data Subject Request HTTP endpoints
type DSRHandler struct {
	dsrService *services.DSRService
}

// NewDSRHandler creates a new DSR handler
func NewDSRHandler(dsrService *services.DSRService) *DSRHandler {
	return &DSRHandler{
		dsrService: dsrService,
	}
}

// ========================================
// USER ENDPOINTS
// ========================================

// CreateDSR creates a new data subject request (user-facing)
func (h *DSRHandler) CreateDSR(c *gin.Context) {
	userID, err := middleware.GetUserID(c)
	if err != nil || userID == uuid.Nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
		return
	}

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

	// Get user email if not provided
	if req.RequesterEmail == "" {
		var email string
		ctx := context.Background()
		h.dsrService.GetPool().QueryRow(ctx, "SELECT email FROM users WHERE id = $1", userID).Scan(&email)
		req.RequesterEmail = email
	}

	// Set source as API
	req.Source = "api"

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

	c.JSON(http.StatusCreated, gin.H{
		"message":        "Ihre Anfrage wurde erfolgreich eingereicht",
		"request_number": dsr.RequestNumber,
		"dsr":            dsr,
	})
}

// GetMyDSRs returns DSRs for the current user
func (h *DSRHandler) GetMyDSRs(c *gin.Context) {
	userID, err := middleware.GetUserID(c)
	if err != nil || userID == uuid.Nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
		return
	}

	dsrs, err := h.dsrService.ListByUser(c.Request.Context(), userID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch requests"})
		return
	}

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

// GetMyDSR returns a specific DSR for the current user
func (h *DSRHandler) GetMyDSR(c *gin.Context) {
	userID, err := middleware.GetUserID(c)
	if err != nil || userID == uuid.Nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
		return
	}

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

	dsr, err := h.dsrService.GetByID(c.Request.Context(), dsrID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Request not found"})
		return
	}

	// Verify ownership
	if dsr.UserID == nil || *dsr.UserID != userID {
		c.JSON(http.StatusForbidden, gin.H{"error": "Access denied"})
		return
	}

	c.JSON(http.StatusOK, dsr)
}

// CancelMyDSR cancels a user's own DSR
func (h *DSRHandler) CancelMyDSR(c *gin.Context) {
	userID, err := middleware.GetUserID(c)
	if err != nil || userID == uuid.Nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
		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.CancelRequest(c.Request.Context(), dsrID, userID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

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

// ========================================
// ADMIN ENDPOINTS
// ========================================

// AdminListDSR returns all DSRs with filters (admin only)
func (h *DSRHandler) AdminListDSR(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	// Parse pagination
	limit := 20
	offset := 0
	if l := c.Query("limit"); l != "" {
		if parsed, err := strconv.Atoi(l); err == nil && parsed > 0 {
			limit = parsed
		}
	}
	if o := c.Query("offset"); o != "" {
		if parsed, err := strconv.Atoi(o); err == nil && parsed >= 0 {
			offset = parsed
		}
	}

	// Parse filters
	filters := models.DSRListFilters{}
	if status := c.Query("status"); status != "" {
		filters.Status = &status
	}
	if reqType := c.Query("request_type"); reqType != "" {
		filters.RequestType = &reqType
	}
	if assignedTo := c.Query("assigned_to"); assignedTo != "" {
		filters.AssignedTo = &assignedTo
	}
	if priority := c.Query("priority"); priority != "" {
		filters.Priority = &priority
	}
	if c.Query("overdue_only") == "true" {
		filters.OverdueOnly = true
	}
	if search := c.Query("search"); search != "" {
		filters.Search = &search
	}
	if from := c.Query("from_date"); from != "" {
		if t, err := time.Parse("2006-01-02", from); err == nil {
			filters.FromDate = &t
		}
	}
	if to := c.Query("to_date"); to != "" {
		if t, err := time.Parse("2006-01-02", to); err == nil {
			filters.ToDate = &t
		}
	}

	dsrs, total, err := h.dsrService.List(c.Request.Context(), filters, limit, offset)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch requests"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"requests": dsrs,
		"total":    total,
		"limit":    limit,
		"offset":   offset,
	})
}

// AdminGetDSR returns a specific DSR (admin only)
func (h *DSRHandler) AdminGetDSR(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
	}

	dsr, err := h.dsrService.GetByID(c.Request.Context(), dsrID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Request not found"})
		return
	}

	c.JSON(http.StatusOK, dsr)
}

// AdminCreateDSR creates a DSR manually (admin only)
func (h *DSRHandler) AdminCreateDSR(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	userID, _ := middleware.GetUserID(c)

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

	// Set source as admin_panel
	if req.Source == "" {
		req.Source = "admin_panel"
	}

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

	c.JSON(http.StatusCreated, gin.H{
		"message":        "Anfrage wurde erstellt",
		"request_number": dsr.RequestNumber,
		"dsr":            dsr,
	})
}

// AdminUpdateDSR updates a DSR (admin only)
func (h *DSRHandler) AdminUpdateDSR(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.UpdateDSRRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	ctx := c.Request.Context()

	// Update status if provided
	if req.Status != nil {
		err = h.dsrService.UpdateStatus(ctx, dsrID, models.DSRStatus(*req.Status), "", &userID)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
	}

	// Update processing notes
	if req.ProcessingNotes != nil {
		h.dsrService.GetPool().Exec(ctx, `
			UPDATE data_subject_requests SET processing_notes = $1, updated_at = NOW() WHERE id = $2
		`, *req.ProcessingNotes, dsrID)
	}

	// Update priority
	if req.Priority != nil {
		h.dsrService.GetPool().Exec(ctx, `
			UPDATE data_subject_requests SET priority = $1, updated_at = NOW() WHERE id = $2
		`, *req.Priority, dsrID)
	}

	// Get updated DSR
	dsr, _ := h.dsrService.GetByID(ctx, dsrID)

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

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

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

	c.JSON(http.StatusOK, stats)
}

// AdminVerifyIdentity verifies the identity of a requester
func (h *DSRHandler) AdminVerifyIdentity(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.VerifyDSRIdentityRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

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

	c.JSON(http.StatusOK, gin.H{"message": "Identität wurde verifiziert"})
}

// AdminAssignDSR assigns a DSR to a user
func (h *DSRHandler) AdminAssignDSR(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 {
		AssigneeID string `json:"assignee_id" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	assigneeID, err := uuid.Parse(req.AssigneeID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid assignee ID"})
		return
	}

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

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

// AdminExtendDSRDeadline extends the deadline for a DSR
func (h *DSRHandler) AdminExtendDSRDeadline(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.ExtendDSRDeadlineRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

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

	c.JSON(http.StatusOK, gin.H{"message": "Frist wurde verlängert"})
}

// AdminCompleteDSR marks a DSR as completed
func (h *DSRHandler) AdminCompleteDSR(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.CompleteDSRRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

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

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

// AdminRejectDSR rejects a DSR
func (h *DSRHandler) AdminRejectDSR(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.RejectDSRRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

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

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

// AdminGetDSRHistory returns the status history for a DSR
func (h *DSRHandler) AdminGetDSRHistory(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
	}

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

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

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

// ========================================
// TEMPLATE ENDPOINTS
// ========================================

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

	ctx := c.Request.Context()
	rows, err := h.dsrService.GetPool().Query(ctx, `
		SELECT id, template_type, name, description, request_types, is_active, sort_order, created_at, updated_at
		FROM dsr_templates ORDER BY sort_order, name
	`)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch templates"})
		return
	}
	defer rows.Close()

	var templates []map[string]interface{}
	for rows.Next() {
		var id uuid.UUID
		var templateType, name string
		var description *string
		var requestTypes []byte
		var isActive bool
		var sortOrder int
		var createdAt, updatedAt time.Time

		err := rows.Scan(&id, &templateType, &name, &description, &requestTypes, &isActive, &sortOrder, &createdAt, &updatedAt)
		if err != nil {
			continue
		}

		templates = append(templates, map[string]interface{}{
			"id":            id,
			"template_type": templateType,
			"name":          name,
			"description":   description,
			"request_types": string(requestTypes),
			"is_active":     isActive,
			"sort_order":    sortOrder,
			"created_at":    createdAt,
			"updated_at":    updatedAt,
		})
	}

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

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

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

	ctx := c.Request.Context()
	rows, err := h.dsrService.GetPool().Query(ctx, `
		SELECT id, template_id, version, language, subject, body_html, body_text,
			   status, published_at, created_by, approved_by, approved_at, created_at, updated_at
		FROM dsr_template_versions WHERE template_id = $1 ORDER BY created_at DESC
	`, templateID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch versions"})
		return
	}
	defer rows.Close()

	var versions []map[string]interface{}
	for rows.Next() {
		var id, tempID uuid.UUID
		var version, language, subject, bodyHTML, bodyText, status string
		var publishedAt, approvedAt *time.Time
		var createdBy, approvedBy *uuid.UUID
		var createdAt, updatedAt time.Time

		err := rows.Scan(&id, &tempID, &version, &language, &subject, &bodyHTML, &bodyText,
			&status, &publishedAt, &createdBy, &approvedBy, &approvedAt, &createdAt, &updatedAt)
		if err != nil {
			continue
		}

		versions = append(versions, map[string]interface{}{
			"id":           id,
			"template_id":  tempID,
			"version":      version,
			"language":     language,
			"subject":      subject,
			"body_html":    bodyHTML,
			"body_text":    bodyText,
			"status":       status,
			"published_at": publishedAt,
			"created_by":   createdBy,
			"approved_by":  approvedBy,
			"approved_at":  approvedAt,
			"created_at":   createdAt,
			"updated_at":   updatedAt,
		})
	}

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

// AdminCreateDSRTemplateVersion creates a new template version
func (h *DSRHandler) AdminCreateDSRTemplateVersion(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

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

	userID, _ := middleware.GetUserID(c)

	var req struct {
		Version  string `json:"version" binding:"required"`
		Language string `json:"language"`
		Subject  string `json:"subject" binding:"required"`
		BodyHTML string `json:"body_html" binding:"required"`
		BodyText string `json:"body_text"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	if req.Language == "" {
		req.Language = "de"
	}

	ctx := c.Request.Context()
	var versionID uuid.UUID
	err = h.dsrService.GetPool().QueryRow(ctx, `
		INSERT INTO dsr_template_versions (template_id, version, language, subject, body_html, body_text, created_by)
		VALUES ($1, $2, $3, $4, $5, $6, $7)
		RETURNING id
	`, templateID, req.Version, req.Language, req.Subject, req.BodyHTML, req.BodyText, userID).Scan(&versionID)

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create version"})
		return
	}

	c.JSON(http.StatusCreated, gin.H{
		"message": "Version wurde erstellt",
		"id":      versionID,
	})
}

// AdminPublishDSRTemplateVersion publishes a template version
func (h *DSRHandler) AdminPublishDSRTemplateVersion(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

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

	userID, _ := middleware.GetUserID(c)

	ctx := c.Request.Context()
	_, err = h.dsrService.GetPool().Exec(ctx, `
		UPDATE dsr_template_versions
		SET status = 'published', published_at = NOW(), approved_by = $1, approved_at = NOW(), updated_at = NOW()
		WHERE id = $2
	`, userID, versionID)

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to publish version"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Version wurde veröffentlicht"})
}

// AdminGetPublishedDSRTemplates returns all published templates for selection
func (h *DSRHandler) AdminGetPublishedDSRTemplates(c *gin.Context) {
	if !middleware.IsAdmin(c) && !middleware.IsDSB(c) {
		c.JSON(http.StatusForbidden, gin.H{"error": "Admin or DSB access required"})
		return
	}

	requestType := c.Query("request_type")
	language := c.DefaultQuery("language", "de")

	ctx := c.Request.Context()
	query := `
		SELECT t.id, t.template_type, t.name, t.description,
			   v.id as version_id, v.version, v.subject, v.body_html, v.body_text
		FROM dsr_templates t
		JOIN dsr_template_versions v ON t.id = v.template_id
		WHERE t.is_active = TRUE AND v.status = 'published' AND v.language = $1
	`
	args := []interface{}{language}

	if requestType != "" {
		query += ` AND t.request_types @> $2::jsonb`
		args = append(args, `["`+requestType+`"]`)
	}

	query += " ORDER BY t.sort_order, t.name"

	rows, err := h.dsrService.GetPool().Query(ctx, query, args...)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch templates"})
		return
	}
	defer rows.Close()

	var templates []map[string]interface{}
	for rows.Next() {
		var templateID, versionID uuid.UUID
		var templateType, name, version, subject, bodyHTML, bodyText string
		var description *string

		err := rows.Scan(&templateID, &templateType, &name, &description, &versionID, &version, &subject, &bodyHTML, &bodyText)
		if err != nil {
			continue
		}

		templates = append(templates, map[string]interface{}{
			"template_id":   templateID,
			"template_type": templateType,
			"name":          name,
			"description":   description,
			"version_id":    versionID,
			"version":       version,
			"subject":       subject,
			"body_html":     bodyHTML,
			"body_text":     bodyText,
		})
	}

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

// ========================================
// 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"})
}
