package mailv2

import (
	"context"
	"time"

	"github.com/mailgun/mailgun-go/v4"
	"github.com/sendgrid/sendgrid-go"
)

const (
	AttachmentDispositionAttachment = "attachment"
)

var (
	defaultFrom       string = "no-reply@tidbcloud.com"
	sgTemplateName2id        = map[string]string{}
)

type attachment struct {
	Filename string
	//ReaderCloser io.ReadCloser
	Data        []byte
	Disposition string // such as: attachment
	MimeType    string // such as: application/pdf
}

// SendMailOpts Please create it by NewDefaultSendMailOpts
type SendMailOpts struct {
	Track        bool
	DeliveryTime time.Time
	FromAddr     string
	CC           []string
	Attachments  []attachment
}

func NewDefaultSendMailOpts() *SendMailOpts {
	return &SendMailOpts{
		Track:        true,
		DeliveryTime: time.Now(),
		FromAddr:     defaultFrom,
	}
}

func (opts *SendMailOpts) WithTrack(track bool) *SendMailOpts {
	opts.Track = track
	return opts
}

func (opts *SendMailOpts) WithDeliveryTime(t time.Time) *SendMailOpts {
	opts.DeliveryTime = t
	return opts
}

func (opts *SendMailOpts) WithFromAddr(fromAddr string) *SendMailOpts {
	opts.FromAddr = fromAddr
	return opts
}

func (opts *SendMailOpts) WithCC(cc []string) *SendMailOpts {
	opts.CC = cc
	return opts
}

func (opts *SendMailOpts) WithAttachments(filename string, data []byte, mimeType, disposition string) *SendMailOpts {
	opts.Attachments = append(opts.Attachments, attachment{
		Filename:    filename,
		Data:        data,
		MimeType:    mimeType,
		Disposition: disposition,
	})
	return opts
}

type Facade interface {
	SendMailWithTemplate(ctx context.Context, to []string, subject, templateName string, vars map[string]string, opts *SendMailOpts) error
	SendMailWithTemplateID(ctx context.Context, to []string, subject, templateID string, vars map[string]string, opts *SendMailOpts) error
}

func NewFakeMailFacade() *fakeMailFacade {
	return &fakeMailFacade{}
}

type fakeMailFacade struct{}

func (m *fakeMailFacade) SendMailWithTemplate(ctx context.Context, to []string, subject, templateName string, vars map[string]string, opts *SendMailOpts) error {
	return nil
}

func (m *fakeMailFacade) SendMailWithTemplateID(ctx context.Context, to []string, subject, templateID string, vars map[string]string, opts *SendMailOpts) error {
	return nil
}

func NewMailProvider(
	mailgunCli mailgun.Mailgun,
	sendgridCli *sendgrid.Client,
	sendgridTemplateName2id map[string]string,
) Facade {
	sgTemplateName2id = sendgridTemplateName2id
	//return NewMailgun(mailgunCli)
	return NewSendgrid(sendgridCli)
}

func SetDefaultFromMailAddr(addr string) {
	defaultFrom = addr
}
