package handlers

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

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

// PublishVersion publishes an approved version
// POST /api/v1/admin/email-template-versions/:id/publish
func (h *EmailTemplateHandler) PublishVersion(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid version ID"})
		return
	}

	role, exists := c.Get("user_role")
	if !exists || (role != "data_protection_officer" && role != "admin" && role != "super_admin") {
		c.JSON(http.StatusForbidden, gin.H{"error": "insufficient permissions"})
		return
	}

	userID, _ := c.Get("user_id")
	uid, _ := uuid.Parse(userID.(string))

	if err := h.service.PublishVersion(c.Request.Context(), id, uid); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "version published"})
}

// GetApprovals returns approval history for a version
// GET /api/v1/admin/email-template-versions/:id/approvals
func (h *EmailTemplateHandler) GetApprovals(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid version ID"})
		return
	}

	approvals, err := h.service.GetApprovals(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"approvals": approvals})
}

// PreviewVersion renders a preview of an email template version
// POST /api/v1/admin/email-template-versions/:id/preview
func (h *EmailTemplateHandler) PreviewVersion(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid version ID"})
		return
	}

	var req struct {
		Variables map[string]string `json:"variables"`
	}
	c.ShouldBindJSON(&req)

	version, err := h.service.GetVersionByID(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "version not found"})
		return
	}

	// Use default test values if not provided
	if req.Variables == nil {
		req.Variables = map[string]string{
			"user_name":         "Max Mustermann",
			"user_email":        "max@example.com",
			"login_url":         "https://breakpilot.app/login",
			"support_email":     "support@breakpilot.app",
			"verification_url":  "https://breakpilot.app/verify?token=abc123",
			"verification_code": "123456",
			"expires_in":        "24 Stunden",
			"reset_url":         "https://breakpilot.app/reset?token=xyz789",
			"reset_code":        "RESET123",
			"ip_address":        "192.168.1.1",
			"device_info":       "Chrome auf Windows 11",
			"changed_at":        time.Now().Format("02.01.2006 15:04"),
			"enabled_at":        time.Now().Format("02.01.2006 15:04"),
			"disabled_at":       time.Now().Format("02.01.2006 15:04"),
			"support_url":       "https://breakpilot.app/support",
			"security_url":      "https://breakpilot.app/account/security",
			"login_time":        time.Now().Format("02.01.2006 15:04"),
			"location":          "Berlin, Deutschland",
			"activity_type":     "Mehrere fehlgeschlagene Login-Versuche",
			"activity_time":     time.Now().Format("02.01.2006 15:04"),
			"locked_at":         time.Now().Format("02.01.2006 15:04"),
			"reason":            "Zu viele fehlgeschlagene Login-Versuche",
			"unlock_time":       time.Now().Add(30 * time.Minute).Format("02.01.2006 15:04"),
			"unlocked_at":       time.Now().Format("02.01.2006 15:04"),
			"requested_at":      time.Now().Format("02.01.2006"),
			"deletion_date":     time.Now().AddDate(0, 0, 30).Format("02.01.2006"),
			"cancel_url":        "https://breakpilot.app/cancel-deletion?token=cancel123",
			"data_info":         "Benutzerdaten, Zustimmungshistorie, Audit-Logs",
			"deleted_at":        time.Now().Format("02.01.2006"),
			"feedback_url":      "https://breakpilot.app/feedback",
			"download_url":      "https://breakpilot.app/export/download?token=export123",
			"file_size":         "2.3 MB",
			"old_email":         "alt@example.com",
			"new_email":         "neu@example.com",
			"document_name":     "Datenschutzerklärung",
			"document_type":     "privacy",
			"version":           "2.0.0",
			"consent_url":       "https://breakpilot.app/consent",
			"deadline":          time.Now().AddDate(0, 0, 14).Format("02.01.2006"),
			"days_left":         "7",
			"hours_left":        "24 Stunden",
			"consequences":      "Ohne Ihre Zustimmung wird Ihr Konto suspendiert.",
			"suspended_at":      time.Now().Format("02.01.2006 15:04"),
			"documents":         "- Datenschutzerklärung v2.0.0\n- AGB v1.5.0",
		}
	}

	preview, err := h.service.RenderTemplate(version, req.Variables)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, preview)
}

// SendTestEmail sends a test email
// POST /api/v1/admin/email-template-versions/:id/send-test
func (h *EmailTemplateHandler) SendTestEmail(c *gin.Context) {
	idStr := c.Param("id")
	id, err := uuid.Parse(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid version ID"})
		return
	}

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

	version, err := h.service.GetVersionByID(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "version not found"})
		return
	}

	// Get template to find type
	template, err := h.service.GetTemplateByID(c.Request.Context(), version.TemplateID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "template not found"})
		return
	}

	userID, _ := c.Get("user_id")
	uid, _ := uuid.Parse(userID.(string))

	// Send test email
	if err := h.service.SendEmail(c.Request.Context(), template.Type, version.Language, req.Recipient, req.Variables, &uid); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "test email sent"})
}

// GetSettings returns global email settings
// GET /api/v1/admin/email-templates/settings
func (h *EmailTemplateHandler) GetSettings(c *gin.Context) {
	settings, err := h.service.GetSettings(c.Request.Context())
	if err != nil {
		// Return default settings if none exist
		c.JSON(http.StatusOK, gin.H{
			"company_name":    "BreakPilot",
			"sender_name":     "BreakPilot",
			"sender_email":    "noreply@breakpilot.app",
			"primary_color":   "#2563eb",
			"secondary_color": "#64748b",
		})
		return
	}
	c.JSON(http.StatusOK, settings)
}

// UpdateSettings updates global email settings
// PUT /api/v1/admin/email-templates/settings
func (h *EmailTemplateHandler) UpdateSettings(c *gin.Context) {
	var req models.UpdateEmailTemplateSettingsRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	userID, _ := c.Get("user_id")
	uid, _ := uuid.Parse(userID.(string))

	if err := h.service.UpdateSettings(c.Request.Context(), &req, uid); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "settings updated"})
}

// GetEmailStats returns email statistics
// GET /api/v1/admin/email-templates/stats
func (h *EmailTemplateHandler) GetEmailStats(c *gin.Context) {
	stats, err := h.service.GetEmailStats(c.Request.Context())
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, stats)
}

// GetSendLogs returns email send logs
// GET /api/v1/admin/email-templates/logs
func (h *EmailTemplateHandler) GetSendLogs(c *gin.Context) {
	limitStr := c.DefaultQuery("limit", "50")
	offsetStr := c.DefaultQuery("offset", "0")

	limit, _ := strconv.Atoi(limitStr)
	offset, _ := strconv.Atoi(offsetStr)

	if limit > 100 {
		limit = 100
	}

	logs, total, err := h.service.GetSendLogs(c.Request.Context(), limit, offset)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"logs": logs, "total": total})
}

// GetDefaultContent returns default template content for a type
// GET /api/v1/admin/email-templates/default/:type
func (h *EmailTemplateHandler) GetDefaultContent(c *gin.Context) {
	templateType := c.Param("type")
	language := c.DefaultQuery("language", "de")

	subject, bodyHTML, bodyText := h.service.GetDefaultTemplateContent(templateType, language)

	c.JSON(http.StatusOK, gin.H{
		"subject":   subject,
		"body_html": bodyHTML,
		"body_text": bodyText,
	})
}

// InitializeTemplates initializes default email templates
// POST /api/v1/admin/email-templates/initialize
func (h *EmailTemplateHandler) InitializeTemplates(c *gin.Context) {
	role, exists := c.Get("user_role")
	if !exists || (role != "admin" && role != "super_admin") {
		c.JSON(http.StatusForbidden, gin.H{"error": "insufficient permissions"})
		return
	}

	if err := h.service.InitDefaultTemplates(c.Request.Context()); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "default templates initialized"})
}
