package email

import (
	"context"
	"fmt"
	"time"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/credentials"
	"github.com/aws/aws-sdk-go-v2/service/ses"
	"github.com/aws/aws-sdk-go-v2/service/ses/types"
)

// SESSettings configures AWS SES (ported from app-cloudep-notification-service).
type SESSettings struct {
	Sort         int
	Region       string
	AccessKey    string
	SecretKey    string
	SessionToken string
	SendTimeout  time.Duration
}

// SESSender delivers email via AWS SES.
type SESSender struct {
	name    string
	sort    int
	client  *ses.Client
	timeout time.Duration
}

// NewSESSender builds an SES provider.
func NewSESSender(cfg SESSettings) (*SESSender, error) {
	if cfg.Region == "" {
		return nil, fmt.Errorf("email ses: region is required")
	}
	if cfg.AccessKey == "" || cfg.SecretKey == "" {
		return nil, fmt.Errorf("email ses: access key and secret key are required")
	}
	timeout := cfg.SendTimeout
	if timeout <= 0 {
		timeout = 90 * time.Second
	}

	awsCfg := aws.Config{
		Region: cfg.Region,
		Credentials: credentials.NewStaticCredentialsProvider(
			cfg.AccessKey,
			cfg.SecretKey,
			cfg.SessionToken,
		),
	}

	return &SESSender{
		name:    "ses",
		sort:    cfg.Sort,
		client:  ses.NewFromConfig(awsCfg),
		timeout: timeout,
	}, nil
}

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

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

	sendCtx, cancel := context.WithTimeout(ctx, s.timeout)
	defer cancel()

	out, err := s.client.SendEmail(sendCtx, &ses.SendEmailInput{
		Source: aws.String(from),
		Destination: &types.Destination{
			ToAddresses: append([]string(nil), msg.To...),
		},
		Message: &types.Message{
			Subject: &types.Content{
				Charset: aws.String("UTF-8"),
				Data:    aws.String(msg.Subject),
			},
			Body: &types.Body{
				Html: &types.Content{
					Charset: aws.String("UTF-8"),
					Data:    aws.String(msg.Body),
				},
			},
		},
	})
	if err != nil {
		return "", fmt.Errorf("email ses: %w", err)
	}
	if out.MessageId == nil || *out.MessageId == "" {
		return "", fmt.Errorf("email ses: empty message id")
	}
	return *out.MessageId, nil
}
