package template_test

import (
	"testing"

	"gateway/internal/model/notification/domain/enum"
	domtpl "gateway/internal/model/notification/domain/template"
	"gateway/internal/model/notification/template"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestRenderer_Render_VerifyEmailZhTW(t *testing.T) {
	r := template.NewRenderer(template.DefaultRegistry(), domtpl.LocaleZhTW, domtpl.LocaleEnUS)
	out, err := r.Render(enum.NotifyVerifyEmail, domtpl.LocaleZhTW, map[string]any{
		domtpl.VarCode:      "123456",
		domtpl.VarExpiresIn: 300,
	})
	require.NoError(t, err)
	assert.Contains(t, out.Subject, "驗證碼")
	assert.Contains(t, out.Body, "123456")
	assert.Contains(t, out.Body, "300")
}

func TestRenderer_Render_LocaleFallback(t *testing.T) {
	r := template.NewRenderer(template.DefaultRegistry(), domtpl.LocaleZhTW, domtpl.LocaleEnUS)
	out, err := r.Render(enum.NotifyVerifyEmail, "ja-jp", map[string]any{
		domtpl.VarCode:      "999999",
		domtpl.VarExpiresIn: 60,
	})
	require.NoError(t, err)
	assert.Contains(t, out.Subject, "驗證")
}

func TestRenderer_Render_MissingVar(t *testing.T) {
	r := template.NewRenderer(template.DefaultRegistry())
	_, err := r.Render(enum.NotifyVerifyPhone, domtpl.LocaleZhTW, map[string]any{domtpl.VarCode: "1"})
	require.Error(t, err)
	assert.Contains(t, err.Error(), domtpl.VarExpiresIn)
}

func TestRenderer_Render_VerifyPhoneSMS(t *testing.T) {
	r := template.NewRenderer(template.DefaultRegistry())
	out, err := r.Render(enum.NotifyVerifyPhone, domtpl.LocaleEnUS, map[string]any{
		domtpl.VarCode:      "654321",
		domtpl.VarExpiresIn: 300,
	})
	require.NoError(t, err)
	assert.Contains(t, out.SMSText, "654321")
	assert.Empty(t, out.Body)
}

func TestRegistry_Lookup_UnknownKind(t *testing.T) {
	_, err := template.DefaultRegistry().Lookup(enum.NotifyKind("unknown"), domtpl.LocaleZhTW)
	require.Error(t, err)
	assert.Contains(t, err.Error(), "unknown kind")
}

func TestRenderer_Render_EscapesHTMLInBody(t *testing.T) {
	r := template.NewRenderer(template.DefaultRegistry(), domtpl.LocaleZhTW, domtpl.LocaleEnUS)
	out, err := r.Render(enum.NotifyVerifyEmail, domtpl.LocaleZhTW, map[string]any{
		domtpl.VarCode:      "<script>alert(1)</script>",
		domtpl.VarExpiresIn: 300,
	})
	require.NoError(t, err)
	assert.NotContains(t, out.Body, "<script>")
	assert.Contains(t, out.Body, "&lt;script&gt;")
}
