package mailgun

import (
	"context"
	"time"

	"github.com/mailgun/mailgun-go/v4"
	"go.uber.org/zap"
)

type mailgunEmailer struct {
	config  MailgunConfigurationProvider
	logger  *zap.Logger
	Mailgun *mailgun.MailgunImpl
}

func NewEmailer(config MailgunConfigurationProvider, logger *zap.Logger) Emailer {
	logger = logger.Named("mailgun-emailer")

	// Initialize Mailgun client
	mg := mailgun.NewMailgun(config.GetDomainName(), config.GetAPIKey())
	mg.SetAPIBase(config.GetAPIBase()) // Override to support our custom email requirements.

	logger.Info("✓ Mailgun emailer initialized",
		zap.String("domain", config.GetDomainName()),
		zap.String("api_base", config.GetAPIBase()))

	return &mailgunEmailer{
		config:  config,
		logger:  logger,
		Mailgun: mg,
	}
}

func (me *mailgunEmailer) Send(ctx context.Context, sender, subject, recipient, body string) error {
	me.logger.Debug("Sending email",
		zap.String("sender", sender),
		zap.String("recipient", recipient),
		zap.String("subject", subject))

	message := me.Mailgun.NewMessage(sender, subject, "", recipient)
	message.SetHtml(body)

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()

	// Send the message with a 10 second timeout
	resp, id, err := me.Mailgun.Send(ctx, message)

	if err != nil {
		me.logger.Error("Failed to send email",
			zap.String("sender", sender),
			zap.String("recipient", recipient),
			zap.String("subject", subject),
			zap.Error(err))
		return err
	}

	me.logger.Info("Email sent successfully",
		zap.String("recipient", recipient),
		zap.String("subject", subject),
		zap.String("message_id", id),
		zap.String("response", resp))

	return nil
}

func (me *mailgunEmailer) GetDomainName() string {
	return me.config.GetDomainName()
}

func (me *mailgunEmailer) GetSenderEmail() string {
	return me.config.GetSenderEmail()
}

func (me *mailgunEmailer) GetBackendDomainName() string {
	return me.config.GetBackendDomainName()
}

func (me *mailgunEmailer) GetFrontendDomainName() string {
	return me.config.GetFrontendDomainName()
}

func (me *mailgunEmailer) GetMaintenanceEmail() string {
	return me.config.GetMaintenanceEmail()
}
