package api

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

	"archivmail/config"
	"archivmail/internal/audit"
	"archivmail/internal/smtpoutconfig"
)

// handleGetSMTPOut returns the current SMTP-Out relay config (password masked).
// GET /api/admin/smtp-out — superadmin only.
func (s *Server) handleGetSMTPOut(w http.ResponseWriter, r *http.Request) {
	cfg, err := s.smtpOutStore.Get(r.Context())
	if err != nil {
		writeError(w, http.StatusInternalServerError, err.Error())
		return
	}
	if cfg == nil {
		writeJSON(w, http.StatusOK, map[string]interface{}{"configured": false})
		return
	}
	writeJSON(w, http.StatusOK, map[string]interface{}{"configured": true, "config": cfg})
}

// handleSaveSMTPOut upserts the SMTP-Out relay config and reloads the mailer.
// PUT /api/admin/smtp-out — superadmin only.
func (s *Server) handleSaveSMTPOut(w http.ResponseWriter, r *http.Request) {
	var body smtpoutconfig.SMTPOutConfig
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		writeError(w, http.StatusBadRequest, "invalid body")
		return
	}
	if body.Port == 0 {
		body.Port = 587
	}

	sess := sessionFromCtx(r.Context())
	if err := s.smtpOutStore.Save(r.Context(), body, sess.Username); err != nil {
		writeError(w, http.StatusInternalServerError, err.Error())
		return
	}

	// Reload the mailer at runtime — no restart needed
	if full, err := s.smtpOutStore.GetWithPassword(r.Context()); err == nil && full != nil {
		s.mailer.Reload(config.SMTPOutConfig{
			Host:     full.Host,
			Port:     full.Port,
			User:     full.User,
			Password: full.Password,
			TLS:      full.TLS,
			From:     full.From,
		})
	}

	if s.audlog != nil {
		s.audlog.Log(audit.Entry{
			EventType: "smtp_out_config_saved",
			Username:  sess.Username,
			TenantID:  sess.TenantID,
			IPAddress: s.remoteIP(r),
			Success:   true,
		})
	}

	writeJSON(w, http.StatusOK, map[string]interface{}{"ok": true})
}

// handleDeleteSMTPOut removes the SMTP-Out config and disables the mailer.
// DELETE /api/admin/smtp-out — superadmin only.
func (s *Server) handleDeleteSMTPOut(w http.ResponseWriter, r *http.Request) {
	if err := s.smtpOutStore.Delete(r.Context()); err != nil {
		writeError(w, http.StatusInternalServerError, err.Error())
		return
	}
	// Disable mailer
	s.mailer.Reload(config.SMTPOutConfig{})

	sess := sessionFromCtx(r.Context())
	if s.audlog != nil {
		s.audlog.Log(audit.Entry{
			EventType: "smtp_out_config_deleted",
			Username:  sess.Username,
			TenantID:  sess.TenantID,
			IPAddress: s.remoteIP(r),
			Success:   true,
		})
	}
	writeJSON(w, http.StatusOK, map[string]interface{}{"ok": true})
}

// handleTestSMTPOut sends a test email to the logged-in admin.
// POST /api/admin/smtp-out/test — superadmin only.
func (s *Server) handleTestSMTPOut(w http.ResponseWriter, r *http.Request) {
	if !s.mailer.IsConfigured() {
		writeError(w, http.StatusServiceUnavailable, "SMTP-Out nicht konfiguriert")
		return
	}

	sess := sessionFromCtx(r.Context())
	u, err := s.users.GetByUsername(sess.Username)
	if err != nil || u.Email == "" {
		writeError(w, http.StatusBadRequest, "Keine E-Mail-Adresse für diesen Account")
		return
	}

	html := `<p>Dies ist eine Test-E-Mail von <strong>archivmail</strong>.<br>Der SMTP-Relay ist korrekt konfiguriert.</p>`
	txt := "Dies ist eine Test-E-Mail von archivmail. Der SMTP-Relay ist korrekt konfiguriert."

	if err := s.mailer.Send(u.Email, "archivmail – SMTP-Test", html, txt); err != nil {
		writeError(w, http.StatusBadGateway, "Versand fehlgeschlagen: "+err.Error())
		return
	}

	writeJSON(w, http.StatusOK, map[string]interface{}{
		"ok": true,
		"sent_to": u.Email,
	})
}
