// package snailmail sends email through a pluggable provider (SMTP or Cloudflare).
// The active provider and its credentials are injected via Configure(Settings),
// so the framework never reads application config. Branded message composition
// (templates, logos, copy) stays app-side: apps build an Email and call SendMail.
package snailmail

import (
	"bytes"
	"log"
	"strings"
)

const (
	TYPE_TEXT = iota
	TYPE_HTML
)

// Email is a composed message ready to send. Body holds the already-rendered
// text or HTML.
type Email struct {
	Recipients []string
	Subject    string
	Body       *bytes.Buffer
}

// SMTPSettings holds credentials for the SMTP provider.
type SMTPSettings struct {
	Server      string
	Port        string
	Username    string
	Password    string
	DisplayFrom string
	RequireAuth bool
}

// CloudflareSettings holds credentials for the Cloudflare email provider.
type CloudflareSettings struct {
	AccountID   string
	APIToken    string
	FromAddress string
}

// Settings selects and configures the active email provider. Provider is "smtp"
// (default) or "cloudflare".
type Settings struct {
	Provider   string
	SMTP       SMTPSettings
	Cloudflare CloudflareSettings
}

type sender interface {
	Send(message Email, mailtype int) error
}

var (
	settings     Settings
	activeSender sender
)

// Configure stores the provider credentials and selects the active provider.
// Apps call this once at startup with values from their own config.
func Configure(s Settings) {
	settings = s
	switch strings.ToLower(strings.TrimSpace(s.Provider)) {
	case "cloudflare":
		activeSender = &cloudflareSender{}
		log.Println("mailer: using Cloudflare email provider")
	default:
		activeSender = &smtpSender{}
		log.Println("mailer: using SMTP email provider")
	}
}

// SendMail sends message using the configured provider (defaulting to SMTP if
// Configure was never called).
func SendMail(message Email, mailtype int) error {
	if activeSender == nil {
		activeSender = &smtpSender{}
	}
	return activeSender.Send(message, mailtype)
}
