package controllers

import (
    "net/http"
    "strings"

    "fotbal-club/internal/models"
    "fotbal-club/pkg/email"

    "github.com/gin-gonic/gin"
    "gorm.io/gorm"
)

// NotificationsController handles admin-triggered notifications (emails)
// It reuses the newsletter sending pipeline/templates.
type NotificationsController struct {
    DB           *gorm.DB
    EmailService email.EmailService
}

func NewNotificationsController(db *gorm.DB, emailService email.EmailService) *NotificationsController {
    return &NotificationsController{DB: db, EmailService: emailService}
}

// Common request payload for notifications
// Subject is required; body/content carries HTML. Recipients optional.
// If SendToSubscribers is true, all active newsletter subscribers will be included.
// Optional context identifiers (competition code or match ext ID) are accepted for logging/auditing
// or future template specialization, but are not required for sending right now.
type NotificationRequest struct {
    Subject            string   `json:"subject" binding:"required"`
    Body               string   `json:"body"`
    Content            string   `json:"content"`
    Recipients         []string `json:"recipients"`
    SendToSubscribers  bool     `json:"send_to_subscribers"`
    CompetitionCode    string   `json:"competition_code"`
    MatchExternalID    string   `json:"match_external_id"`
}

// SendCompetitionNotification sends a notification related to a competition
// @Summary Send competition notification (admin)
// @Description Sends a notification email for a competition to selected recipients and/or newsletter subscribers
// @Tags admin
// @Security Bearer
// @Accept json
// @Produce json
// @Param input body NotificationRequest true "Notification payload"
// @Success 200 {object} map[string]any
// @Failure 400 {object} map[string]string
// @Failure 401 {object} map[string]string
// @Failure 403 {object} map[string]string
// @Router /api/v1/admin/notifications/competition [post]
func (nc *NotificationsController) SendCompetitionNotification(c *gin.Context) {
    nc.sendNotification(c)
}

// SendMatchNotification sends a notification related to a match
// @Summary Send match notification (admin)
// @Description Sends a notification email for a match to selected recipients and/or newsletter subscribers
// @Tags admin
// @Security Bearer
// @Accept json
// @Produce json
// @Param input body NotificationRequest true "Notification payload"
// @Success 200 {object} map[string]any
// @Failure 400 {object} map[string]string
// @Failure 401 {object} map[string]string
// @Failure 403 {object} map[string]string
// @Router /api/v1/admin/notifications/match [post]
func (nc *NotificationsController) SendMatchNotification(c *gin.Context) {
    nc.sendNotification(c)
}

// Internal shared implementation
func (nc *NotificationsController) sendNotification(c *gin.Context) {
    // Only admins
    if c.GetString("userRole") != "admin" {
        c.JSON(http.StatusForbidden, gin.H{"error": "Access denied"})
        return
    }

    var input NotificationRequest
    if err := c.ShouldBindJSON(&input); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"})
        return
    }

    // Prefer Body then Content
    body := strings.TrimSpace(input.Body)
    if body == "" {
        body = strings.TrimSpace(input.Content)
    }
    if input.Subject == "" || body == "" {
        c.JSON(http.StatusBadRequest, gin.H{"error": "subject and body/content are required"})
        return
    }

    // Build recipients
    recipients := make([]string, 0, len(input.Recipients)+16)
    // Explicit recipients
    for _, r := range input.Recipients {
        r = strings.TrimSpace(strings.ToLower(r))
        if r != "" {
            recipients = append(recipients, r)
        }
    }

    // Include subscribers if requested
    if input.SendToSubscribers {
        var subs []models.NewsletterSubscription
        if err := nc.DB.Where("is_active = ?", true).Find(&subs).Error; err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load subscribers"})
            return
        }
        for _, s := range subs {
            if s.Email != "" {
                recipients = append(recipients, strings.ToLower(strings.TrimSpace(s.Email)))
            }
        }
    }

    // Dedupe recipients
    uniq := make(map[string]struct{}, len(recipients))
    out := make([]string, 0, len(recipients))
    for _, r := range recipients {
        if r == "" {
            continue
        }
        if _, exists := uniq[r]; !exists {
            uniq[r] = struct{}{}
            out = append(out, r)
        }
    }

    if len(out) == 0 {
        c.JSON(http.StatusBadRequest, gin.H{"error": "No recipients resolved"})
        return
    }

    // Send using newsletter template/pipeline
    data := &email.NewsletterData{
        Subject:    input.Subject,
        Content:    body,
        Recipients: out,
    }

    if err := nc.EmailService.SendNewsletter(data); err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to send notifications"})
        return
    }

    c.JSON(http.StatusOK, gin.H{
        "message":     "Notifications sent",
        "recipients":  len(out),
        "competition": input.CompetitionCode,
        "match":       input.MatchExternalID,
    })
}
