package sendgrid

import (
	"context"
	"fmt"
	"time"

	"github.com/sendgrid/sendgrid-go"
	"github.com/sendgrid/sendgrid-go/helpers/mail"
	"github.com/tidbcloud/pov-service/internal/client/email"
)

type client struct {
	raw *sendgrid.Client
}

func NewClient(apikey string) (email.Client, error) {
	sgCli := sendgrid.NewSendClient(apikey)
	return &client{
		raw: sgCli,
	}, nil
}

func (c *client) SendEmailWithTemplate(
	ctx context.Context,
	req email.SendWithTemplateRequest,
) error {
	fromEmail := mail.NewEmail("", req.From)
	toEmails := make([]*mail.Email, 0, len(req.To))
	ccEmails := make([]*mail.Email, 0, len(req.CC))
	bccEmails := make([]*mail.Email, 0, len(req.BCC))

	for _, to := range req.To {
		if to != "" {
			toEmails = append(toEmails, mail.NewEmail("", to))
		}
	}
	for _, cc := range req.CC {
		if cc != "" {
			ccEmails = append(ccEmails, mail.NewEmail("", cc))
		}
	}
	for _, bcc := range req.BCC {
		if bcc != "" {
			bccEmails = append(bccEmails, mail.NewEmail("", bcc))
		}
	}
	if req.DeliveryTime.IsZero() {
		req.DeliveryTime = time.Now()
	}

	// build personalization
	personalize := mail.NewPersonalization()
	personalize.AddTos(toEmails...)
	personalize.AddCCs(ccEmails...)
	personalize.AddBCCs(bccEmails...)

	for k, v := range req.TemplateVars {
		personalize.SetDynamicTemplateData(k, v)
	}

	// build message
	message := mail.NewV3Mail()
	message.SetFrom(fromEmail)
	message.AddPersonalizations(personalize)
	message.SetTrackingSettings(mail.NewTrackingSettings().SetOpenTracking(mail.NewOpenTrackingSetting().SetEnable(true)))
	message.SetSendAt(int(req.DeliveryTime.Unix()))
	message.SetTemplateID(req.TemplateID)

	// send
	resp, err := c.raw.Send(message)
	if err != nil {
		return err
	}
	if resp.StatusCode >= 400 {
		return fmt.Errorf("send mail failed, code=%d body=%s", resp.StatusCode, resp.Body)
	}
	return nil
}
