package services

import (
	"bytes"
	"fmt"
	"net/smtp"
	"strings"
)

// EmailConfig holds SMTP configuration
type EmailConfig struct {
	Host     string
	Port     int
	Username string
	Password string
	FromName string
	FromAddr string
	BaseURL  string // Frontend URL for links
}

// EmailService handles sending emails
type EmailService struct {
	config EmailConfig
}

// NewEmailService creates a new EmailService
func NewEmailService(config EmailConfig) *EmailService {
	return &EmailService{config: config}
}

// SendEmail sends an email
func (s *EmailService) SendEmail(to, subject, htmlBody, textBody string) error {
	// Build MIME message
	var msg bytes.Buffer

	msg.WriteString(fmt.Sprintf("From: %s <%s>\r\n", s.config.FromName, s.config.FromAddr))
	msg.WriteString(fmt.Sprintf("To: %s\r\n", to))
	msg.WriteString(fmt.Sprintf("Subject: %s\r\n", subject))
	msg.WriteString("MIME-Version: 1.0\r\n")
	msg.WriteString("Content-Type: multipart/alternative; boundary=\"boundary42\"\r\n")
	msg.WriteString("\r\n")

	// Text part
	msg.WriteString("--boundary42\r\n")
	msg.WriteString("Content-Type: text/plain; charset=\"UTF-8\"\r\n")
	msg.WriteString("\r\n")
	msg.WriteString(textBody)
	msg.WriteString("\r\n")

	// HTML part
	msg.WriteString("--boundary42\r\n")
	msg.WriteString("Content-Type: text/html; charset=\"UTF-8\"\r\n")
	msg.WriteString("\r\n")
	msg.WriteString(htmlBody)
	msg.WriteString("\r\n")
	msg.WriteString("--boundary42--\r\n")

	// Send email
	addr := fmt.Sprintf("%s:%d", s.config.Host, s.config.Port)
	auth := smtp.PlainAuth("", s.config.Username, s.config.Password, s.config.Host)

	err := smtp.SendMail(addr, auth, s.config.FromAddr, []string{to}, msg.Bytes())
	if err != nil {
		return fmt.Errorf("failed to send email: %w", err)
	}

	return nil
}

// SendVerificationEmail sends an email verification email
func (s *EmailService) SendVerificationEmail(to, name, token string) error {
	verifyLink := fmt.Sprintf("%s/verify-email?token=%s", s.config.BaseURL, token)

	subject := "Bitte bestätigen Sie Ihre E-Mail-Adresse - BreakPilot"

	textBody := fmt.Sprintf(`Hallo %s,

Willkommen bei BreakPilot!

Bitte bestätigen Sie Ihre E-Mail-Adresse, indem Sie den folgenden Link öffnen:
%s

Dieser Link ist 24 Stunden gültig.

Falls Sie sich nicht bei BreakPilot registriert haben, können Sie diese E-Mail ignorieren.

Mit freundlichen Grüßen,
Ihr BreakPilot Team`, getDisplayName(name), verifyLink)

	htmlBody := s.renderTemplate("verification", map[string]interface{}{
		"Name":       getDisplayName(name),
		"VerifyLink": verifyLink,
	})

	return s.SendEmail(to, subject, htmlBody, textBody)
}

// SendPasswordResetEmail sends a password reset email
func (s *EmailService) SendPasswordResetEmail(to, name, token string) error {
	resetLink := fmt.Sprintf("%s/reset-password?token=%s", s.config.BaseURL, token)

	subject := "Passwort zurücksetzen - BreakPilot"

	textBody := fmt.Sprintf(`Hallo %s,

Sie haben eine Anfrage zum Zurücksetzen Ihres Passworts gestellt.

Klicken Sie auf den folgenden Link, um Ihr Passwort zurückzusetzen:
%s

Dieser Link ist 1 Stunde gültig.

Falls Sie keine Passwort-Zurücksetzung angefordert haben, können Sie diese E-Mail ignorieren.

Mit freundlichen Grüßen,
Ihr BreakPilot Team`, getDisplayName(name), resetLink)

	htmlBody := s.renderTemplate("password_reset", map[string]interface{}{
		"Name":      getDisplayName(name),
		"ResetLink": resetLink,
	})

	return s.SendEmail(to, subject, htmlBody, textBody)
}

// SendNewVersionNotification sends a notification about new document version
func (s *EmailService) SendNewVersionNotification(to, name, documentName, documentType string, deadlineDays int) error {
	consentLink := fmt.Sprintf("%s/app?consent=pending", s.config.BaseURL)

	subject := fmt.Sprintf("Neue Version: %s - Bitte bestätigen Sie innerhalb von %d Tagen", documentName, deadlineDays)

	textBody := fmt.Sprintf(`Hallo %s,

Wir haben unsere %s aktualisiert.

Bitte lesen und bestätigen Sie die neuen Bedingungen innerhalb der nächsten %d Tage:
%s

Falls Sie nicht innerhalb dieser Frist bestätigen, wird Ihr Account vorübergehend gesperrt.

Mit freundlichen Grüßen,
Ihr BreakPilot Team`, getDisplayName(name), documentName, deadlineDays, consentLink)

	htmlBody := s.renderTemplate("new_version", map[string]interface{}{
		"Name":         getDisplayName(name),
		"DocumentName": documentName,
		"DeadlineDays": deadlineDays,
		"ConsentLink":  consentLink,
	})

	return s.SendEmail(to, subject, htmlBody, textBody)
}

// SendConsentReminder sends a consent reminder email
func (s *EmailService) SendConsentReminder(to, name string, documents []string, daysLeft int) error {
	consentLink := fmt.Sprintf("%s/app?consent=pending", s.config.BaseURL)

	urgency := "Erinnerung"
	if daysLeft <= 7 {
		urgency = "Dringend"
	}
	if daysLeft <= 2 {
		urgency = "Letzte Warnung"
	}

	subject := fmt.Sprintf("%s: Noch %d Tage um ausstehende Dokumente zu bestätigen", urgency, daysLeft)

	docList := strings.Join(documents, "\n- ")

	textBody := fmt.Sprintf(`Hallo %s,

Dies ist eine freundliche Erinnerung, dass Sie noch ausstehende rechtliche Dokumente bestätigen müssen.

Ausstehende Dokumente:
- %s

Sie haben noch %d Tage Zeit. Nach Ablauf dieser Frist wird Ihr Account vorübergehend gesperrt.

Bitte bestätigen Sie hier:
%s

Mit freundlichen Grüßen,
Ihr BreakPilot Team`, getDisplayName(name), docList, daysLeft, consentLink)

	htmlBody := s.renderTemplate("reminder", map[string]interface{}{
		"Name":        getDisplayName(name),
		"Documents":   documents,
		"DaysLeft":    daysLeft,
		"Urgency":     urgency,
		"ConsentLink": consentLink,
	})

	return s.SendEmail(to, subject, htmlBody, textBody)
}

// SendAccountSuspendedNotification sends notification when account is suspended
func (s *EmailService) SendAccountSuspendedNotification(to, name string, documents []string) error {
	consentLink := fmt.Sprintf("%s/app?consent=pending", s.config.BaseURL)

	subject := "Ihr Account wurde vorübergehend gesperrt - BreakPilot"

	docList := strings.Join(documents, "\n- ")

	textBody := fmt.Sprintf(`Hallo %s,

Ihr Account wurde vorübergehend gesperrt, da Sie die folgenden rechtlichen Dokumente nicht innerhalb der Frist bestätigt haben:

- %s

Um Ihren Account zu entsperren, bestätigen Sie bitte alle ausstehenden Dokumente:
%s

Sobald Sie alle Dokumente bestätigt haben, wird Ihr Account automatisch entsperrt.

Mit freundlichen Grüßen,
Ihr BreakPilot Team`, getDisplayName(name), docList, consentLink)

	htmlBody := s.renderTemplate("suspended", map[string]interface{}{
		"Name":        getDisplayName(name),
		"Documents":   documents,
		"ConsentLink": consentLink,
	})

	return s.SendEmail(to, subject, htmlBody, textBody)
}

// SendAccountReactivatedNotification sends notification when account is reactivated
func (s *EmailService) SendAccountReactivatedNotification(to, name string) error {
	appLink := fmt.Sprintf("%s/app", s.config.BaseURL)

	subject := "Ihr Account wurde wieder aktiviert - BreakPilot"

	textBody := fmt.Sprintf(`Hallo %s,

Vielen Dank für die Bestätigung der rechtlichen Dokumente!

Ihr Account wurde wieder aktiviert und Sie können BreakPilot wie gewohnt nutzen:
%s

Mit freundlichen Grüßen,
Ihr BreakPilot Team`, getDisplayName(name), appLink)

	htmlBody := s.renderTemplate("reactivated", map[string]interface{}{
		"Name":    getDisplayName(name),
		"AppLink": appLink,
	})

	return s.SendEmail(to, subject, htmlBody, textBody)
}

