package mailimp

import (
	"maps"

	"github.com/tech/sendico/notification/interface/api/localizer"
	"github.com/tech/sendico/notification/internal/server/notificationimp/mail/internal/mailkey"
	mmail "github.com/tech/sendico/notification/internal/server/notificationimp/mail/messagebuilder"
	"github.com/tech/sendico/pkg/domainprovider"
	"github.com/tech/sendico/pkg/localization"
)

type EmailNotificationTemplate struct {
	dp             domainprovider.DomainProvider
	l              localizer.Localizer
	data           localization.LocData
	unsubscribable bool
	hasButton      bool
}

func (m *EmailNotificationTemplate) AddData(key, value string) {
	localization.AddLocData(m.data, key, value)
}

// content:
// Greeting: Welcome,&nbsp;Gregory
// Content: You're receiving this message because you recently signed up for an account.<br><br>Confirm your email address by clicking the button below. This step adds extra security to your business by verifying you own this email.
// LogoLink: link to a logo
// Privacy: Privacy Policy
// PolicyLink: link to a privacy policy
// Unsubscribe: Unsubscribe
// UnsubscribeLink: link to an unsubscribe command
// MessageTitle: message title

func (m *EmailNotificationTemplate) prepareUnsubscribe(msg mmail.Message) error {
	var block string
	if m.unsubscribable {
		var d localization.LocData
		unsubscribe, err := m.l.LocalizeString("mail.template.unsubscribe", msg.Locale())
		if err != nil {
			return err
		}
		localization.AddLocData(d, "Unsubscribe", unsubscribe)
		unsLink, err := m.dp.GetFullLink("account", "unsubscribe", msg.AccountID())
		if err != nil {
			return err
		}
		localization.AddLocData(d, "UnsubscribeLink", unsLink)
		if block, err = renderUnsubscribeBlock(d); err != nil {
			return err
		}
	}
	m.AddData("UnsubscribeBlock", block)
	return nil
}

func (m *EmailNotificationTemplate) prepareButton(_ mmail.Message) error {
	var block string
	if m.hasButton {
		var err error
		if block, err = renderButtonBlock(m.data); err != nil {
			return err
		}
	}
	m.AddData("ButtonBlock", block)
	return nil
}

func (m *EmailNotificationTemplate) SignatureData(msg mmail.Message, content, subj string) (string, error) {
	m.AddData("Content", content)
	m.AddData("MessageTitle", subj)
	logoLink, err := m.dp.GetAPILink("logo", msg.AccountID(), msg.TemplateID())
	if err != nil {
		return "", err
	}
	m.AddData("LogoLink", logoLink)
	privacy, err := m.l.LocalizeString("mail.template.privacy", msg.Locale())
	if err != nil {
		return "", err
	}
	m.AddData("Privacy", privacy)
	ppLink, err := m.dp.GetFullLink("/privacy-policy")
	if err != nil {
		return "", err
	}
	m.AddData("PolicyLink", ppLink)
	if err := m.prepareButton(msg); err != nil {
		return "", err
	}
	if err := m.prepareUnsubscribe(msg); err != nil {
		return "", err
	}

	return renderOneButtonEmail(m.data)
}

func (m *EmailNotificationTemplate) putOnHTMLTemplate(msg mmail.Message, content, subj string) (string, error) {
	greeting, err := m.l.LocalizeTemplate(mailkey.Get(msg.TemplateID(), "greeting"), m.data, nil, msg.Locale())
	if err != nil {
		return "", err
	}
	m.AddData("Greeting", greeting)
	return m.SignatureData(msg, content, subj)
}

func (m *EmailNotificationTemplate) Build(msg mmail.Message) (string, error) {
	if m.data != nil {
		m.data["ServiceName"] = m.l.ServiceName()
		m.data["SupportMail"] = m.l.SupportMail()
		var err error
		if m.data["ServiceOwner"], err = m.l.LocalizeString("service.owner", msg.Locale()); err != nil {
			return "", err
		}
		if m.data["OwnerAddress"], err = m.l.LocalizeString("service.address", msg.Locale()); err != nil {
			return "", err
		}
		if m.data["OwnerPhone"], err = m.l.LocalizeString("service.phone", msg.Locale()); err != nil {
			return "", err
		}
		maps.Copy(m.data, msg.Parameters())
	}
	content, err := mailkey.Body(m.l, m.data, msg.TemplateID(), msg.Locale())
	if err != nil {
		return "", err
	}
	subject, err := mailkey.Subject(m.l, m.data, msg.TemplateID(), msg.Locale())
	if err != nil {
		return "", err
	}
	return m.putOnHTMLTemplate(msg, content, subject)
}

func (t *EmailNotificationTemplate) SetUnsubscribable(isUnsubscribable bool) {
	t.unsubscribable = isUnsubscribable
}

func (t *EmailNotificationTemplate) SetButton(hasButton bool) {
	t.hasButton = hasButton
}

func NewEmailNotification(l localizer.Localizer, dp domainprovider.DomainProvider) *EmailNotificationTemplate {
	p := &EmailNotificationTemplate{
		dp:   dp,
		l:    l,
		data: localization.LocData{},
	}
	p.unsubscribable = false
	p.hasButton = false
	return p
}
