package ports

import "context"

// EmailMessage represents an outbound email.
type EmailMessage struct {
	To      []string
	Cc      []string
	Bcc     []string
	From    string
	Subject string
	Body    string // plain text
	HTML    string // HTML body (preferred when non-empty)
}

// EmailRecipientResult records the transport outcome for one recipient.
type EmailRecipientResult struct {
	Address string `json:"address"`
	Role    string `json:"role"`
	Status  string `json:"status"`
	Error   string `json:"error,omitempty"`
}

// EmailSendResult is the structured delivery result returned by EmailSender.
type EmailSendResult struct {
	SentCount        int                    `json:"sentCount"`
	RecipientResults []EmailRecipientResult `json:"recipientResults"`
	MessageID        string                 `json:"messageId,omitempty"`
}

// EmailSender abstracts email delivery so that the automation layer
// is decoupled from any specific transport (SMTP, SES API, noop logger, etc.).
type EmailSender interface {
	Send(ctx context.Context, msg *EmailMessage) (*EmailSendResult, error)
}

// AcceptedEmailSendResult returns the common success shape for transports that
// accepted all envelope recipients in a single send attempt.
func AcceptedEmailSendResult(msg *EmailMessage, messageID string) *EmailSendResult {
	if msg == nil {
		return &EmailSendResult{}
	}
	recipients := make([]EmailRecipientResult, 0, len(msg.To)+len(msg.Cc)+len(msg.Bcc))
	recipients = appendAcceptedEmailRecipients(recipients, "to", msg.To)
	recipients = appendAcceptedEmailRecipients(recipients, "cc", msg.Cc)
	recipients = appendAcceptedEmailRecipients(recipients, "bcc", msg.Bcc)
	return &EmailSendResult{
		SentCount:        len(recipients),
		RecipientResults: recipients,
		MessageID:        messageID,
	}
}

func appendAcceptedEmailRecipients(results []EmailRecipientResult, role string, addresses []string) []EmailRecipientResult {
	for _, address := range addresses {
		results = append(results, EmailRecipientResult{
			Address: address,
			Role:    role,
			Status:  "accepted",
		})
	}
	return results
}
