package email

import (
	"context"
	"fmt"

	"github.com/google/uuid"
	"gopkg.in/gomail.v2"
)

// SMTPSettings configures an SMTP Sender (ported from app-cloudep-notification-service).
type SMTPSettings struct {
	Sort     int
	Host     string
	Port     int
	Username string
	Password string
}

// SMTPSender delivers email via SMTP (gomail).
type SMTPSender struct {
	name   string
	sort   int
	dialer *gomail.Dialer
}

// NewSMTPSender builds an SMTP provider. Host and Port are required.
func NewSMTPSender(cfg SMTPSettings) (*SMTPSender, error) {
	if cfg.Host == "" {
		return nil, fmt.Errorf("email smtp: host is required")
	}
	if cfg.Port <= 0 {
		return nil, fmt.Errorf("email smtp: port must be positive")
	}
	return &SMTPSender{
		name:   "smtp",
		sort:   cfg.Sort,
		dialer: gomail.NewDialer(cfg.Host, cfg.Port, cfg.Username, cfg.Password),
	}, nil
}

func (s *SMTPSender) Name() string { return s.name }
func (s *SMTPSender) Sort() int    { return s.sort }

func (s *SMTPSender) Send(ctx context.Context, msg *Message) (string, error) {
	if err := ctx.Err(); err != nil {
		return "", err
	}
	if msg == nil || len(msg.To) == 0 {
		return "", fmt.Errorf("email smtp: message or recipients missing")
	}
	from := msg.From
	if from == "" {
		return "", fmt.Errorf("email smtp: from address is required")
	}

	m := gomail.NewMessage()
	m.SetHeader("From", from)
	m.SetHeader("To", msg.To...)
	m.SetHeader("Subject", msg.Subject)
	m.SetBody("text/html", msg.Body)

	// gomail does not accept context; honor cancellation before blocking I/O.
	if err := ctx.Err(); err != nil {
		return "", err
	}
	if err := s.dialer.DialAndSend(m); err != nil {
		return "", fmt.Errorf("email smtp: %w", err)
	}
	return uuid.NewString(), nil
}
