package mail

import (
	"github.com/mitchellh/mapstructure"
	"github.com/tech/sendico/notification/interface/api/localizer"
	notification "github.com/tech/sendico/notification/interface/services/notification/config"
	mi "github.com/tech/sendico/notification/internal/server/notificationimp/mail/internal"
	mb "github.com/tech/sendico/notification/internal/server/notificationimp/mail/messagebuilder"
	"github.com/tech/sendico/pkg/domainprovider"
	"github.com/tech/sendico/pkg/merrors"
	"github.com/tech/sendico/pkg/messaging"
	"github.com/tech/sendico/pkg/mlogger"
	"go.uber.org/zap"
)

type Client interface {
	Send(r mb.MailBuilder) error
	MailBuilder() mb.MailBuilder
}

type Config = notification.Config

func createMailClient(logger mlogger.Logger, producer messaging.Producer, l localizer.Localizer, dp domainprovider.DomainProvider, config *Config) (Client, error) {
	if len(config.Driver) == 0 {
		return nil, merrors.InvalidArgument("Mail driver name must be provided", "config.driver")
	}
	logger.Info("Connecting mail client...", zap.String("driver", config.Driver))
	if config.Driver == "dummy" {
		return mi.NewDummy(logger)
	}
	if config.Driver == "sendgrid" {
		var sgconfig mi.SendGridConfig
		if err := mapstructure.Decode(config.Settings, &sgconfig); err != nil {
			logger.Error("Failed to decode driver settings", zap.Error(err), zap.String("driver", config.Driver))
			return nil, err
		}
		return mi.NewSendGridNotifier(logger, producer, &sgconfig)
	}
	if config.Driver == "client" {
		var gsmconfing mi.GSMConfig
		if err := mapstructure.Decode(config.Settings, &gsmconfing); err != nil {
			logger.Error("Failed to decode driver settings", zap.Error(err), zap.String("driver", config.Driver))
			return nil, err
		}

		return mi.NewClient(logger, l, dp, &gsmconfing), nil
	}
	return nil, merrors.InvalidArgument("Unkwnown mail driver: "+config.Driver, "config.driver")
}

func CreateMailClient(logger mlogger.Logger, sender string, producer messaging.Producer, l localizer.Localizer, dp domainprovider.DomainProvider, config *Config) (Client, error) {
	return NewAmpliMailer(logger, sender, producer, l, dp, config)
}
