package notifications

import (
	"encoding/json"
	"fmt"
	"net/http"

	"go.uber.org/zap"

	"github.com/veylant/ia-gateway/internal/apierror"
	"github.com/veylant/ia-gateway/internal/middleware"
)

// Handler handles POST /v1/notifications/send — sends a budget alert email.
// Requires a valid JWT (caller must be authenticated).
type Handler struct {
	mailer *Mailer
	logger *zap.Logger
}

// NewHandler creates a Handler. mailer must not be nil.
func NewHandler(mailer *Mailer, logger *zap.Logger) *Handler {
	return &Handler{mailer: mailer, logger: logger}
}

// SendRequest is the JSON body for POST /v1/notifications/send.
type SendRequest struct {
	To        string  `json:"to"`         // recipient email address
	AlertName string  `json:"alert_name"` // human-readable rule name
	Scope     string  `json:"scope"`      // "global" | provider name
	Spend     float64 `json:"spend"`      // current spend for the scope
	Threshold float64 `json:"threshold"`  // configured threshold
	Type      string  `json:"type"`       // "budget_exceeded" | "budget_warning"
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	reqID := middleware.RequestIDFromContext(r.Context())

	var req SendRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		apierror.WriteErrorWithRequestID(w, &apierror.APIError{
			Type: "invalid_request_error", Message: "Invalid JSON body",
			Code: "invalid_request", HTTPStatus: http.StatusBadRequest,
		}, reqID)
		return
	}
	if req.To == "" {
		apierror.WriteErrorWithRequestID(w, &apierror.APIError{
			Type: "invalid_request_error", Message: "Field 'to' is required",
			Code: "invalid_request", HTTPStatus: http.StatusBadRequest,
		}, reqID)
		return
	}
	if req.AlertName == "" {
		apierror.WriteErrorWithRequestID(w, &apierror.APIError{
			Type: "invalid_request_error", Message: "Field 'alert_name' is required",
			Code: "invalid_request", HTTPStatus: http.StatusBadRequest,
		}, reqID)
		return
	}

	subject, html := buildEmail(req)
	if err := h.mailer.Send(Message{To: req.To, Subject: subject, HTML: html}); err != nil {
		h.logger.Warn("notification email send failed",
			zap.Error(err),
			zap.String("to", req.To),
			zap.String("alert", req.AlertName),
			zap.String("request_id", reqID),
		)
		apierror.WriteErrorWithRequestID(w, &apierror.APIError{
			Type:       "api_error",
			Message:    "Failed to send notification email — check SMTP configuration",
			Code:       "email_send_failed",
			HTTPStatus: http.StatusServiceUnavailable,
		}, reqID)
		return
	}

	h.logger.Info("notification email sent",
		zap.String("to", req.To),
		zap.String("alert", req.AlertName),
		zap.String("type", req.Type),
	)
	w.WriteHeader(http.StatusNoContent)
}

// buildEmail returns the subject and HTML body for a budget alert notification.
func buildEmail(req SendRequest) (subject, html string) {
	isExceeded := req.Type == "budget_exceeded"

	scopeLabel := req.Scope
	if req.Scope == "global" {
		scopeLabel = "Tous fournisseurs"
	}

	pct := 0.0
	if req.Threshold > 0 {
		pct = (req.Spend / req.Threshold) * 100
	}

	accentColor := "#f59e0b" // warning amber
	statusLabel := "Alerte 80 % — seuil bientôt atteint"
	emoji := "⚠️"
	if isExceeded {
		accentColor = "#ef4444" // destructive red
		statusLabel = "Seuil dépassé"
		emoji = "🚨"
	}

	subject = fmt.Sprintf("[Veylant IA] %s %s : %s", emoji, statusLabel, req.AlertName)

	html = fmt.Sprintf(`<!DOCTYPE html>
<html lang="fr">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head>
<body style="margin:0;padding:24px;background:#f3f4f6;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
  <div style="max-width:500px;margin:0 auto;background:#ffffff;border-radius:10px;border:1px solid #e5e7eb;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,.08);">

    <!-- Header band -->
    <div style="background:%s;padding:20px 28px;">
      <p style="margin:0;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.75);">Veylant IA · Governance Hub</p>
      <h1 style="margin:6px 0 0;font-size:20px;font-weight:700;color:#fff;">%s</h1>
    </div>

    <!-- Body -->
    <div style="padding:28px;">
      <h2 style="margin:0 0 18px;font-size:16px;font-weight:600;color:#111827;">Règle : %s</h2>

      <table style="width:100%%;border-collapse:collapse;font-size:14px;color:#374151;">
        <tr>
          <td style="padding:10px 0;border-bottom:1px solid #f3f4f6;color:#6b7280;">Périmètre</td>
          <td style="padding:10px 0;border-bottom:1px solid #f3f4f6;text-align:right;font-weight:500;text-transform:capitalize;">%s</td>
        </tr>
        <tr>
          <td style="padding:10px 0;border-bottom:1px solid #f3f4f6;color:#6b7280;">Dépenses actuelles</td>
          <td style="padding:10px 0;border-bottom:1px solid #f3f4f6;text-align:right;font-weight:700;color:%s;">$%.6f</td>
        </tr>
        <tr>
          <td style="padding:10px 0;border-bottom:1px solid #f3f4f6;color:#6b7280;">Seuil configuré</td>
          <td style="padding:10px 0;border-bottom:1px solid #f3f4f6;text-align:right;font-weight:500;">$%.6f</td>
        </tr>
        <tr>
          <td style="padding:10px 0;color:#6b7280;">Consommation</td>
          <td style="padding:10px 0;text-align:right;font-weight:700;color:%s;">%.1f %%</td>
        </tr>
      </table>

      <!-- Progress bar -->
      <div style="margin-top:18px;background:#f3f4f6;border-radius:99px;height:8px;overflow:hidden;">
        <div style="height:8px;border-radius:99px;background:%s;width:%.0f%%;transition:width .3s;"></div>
      </div>
      <p style="margin:6px 0 0;font-size:12px;color:#6b7280;text-align:right;">%.1f %% du seuil</p>
    </div>

    <!-- Footer -->
    <div style="padding:16px 28px;background:#f9fafb;border-top:1px solid #e5e7eb;">
      <p style="margin:0;font-size:12px;color:#9ca3af;line-height:1.5;">
        Cet email a été envoyé automatiquement par <strong style="color:#6b7280;">Veylant IA</strong>.<br>
        Gérez vos règles d'alerte dans <em>Paramètres → Notifications</em>.
      </p>
    </div>

  </div>
</body>
</html>`,
		accentColor, statusLabel,
		req.AlertName,
		scopeLabel,
		accentColor, req.Spend,
		req.Threshold,
		accentColor, pct,
		accentColor, pct,
		pct,
	)

	return subject, html
}
