1package i18n
2
3import (
4	"embed"
5	"github.com/jeandeaual/go-locale"
6	"github.com/nicksnyder/go-i18n/v2/i18n"
7	"golang.org/x/text/language"
8	"gopkg.in/yaml.v2"
9	"log"
10	"strings"
11)
12
13//go:embed *.yaml
14var localeFiles embed.FS
15
16var localizer *i18n.Localizer
17
18// Initialize initializes the i18n bundle and localizer
19func Initialize() {
20	lang := getPreferredLanguage()
21
22	bundle := i18n.NewBundle(language.English)
23	bundle.RegisterUnmarshalFunc("yaml", yaml.Unmarshal)
24
25	// Load English translations first
26	if err := loadTranslations(bundle, "en.yaml"); err != nil {
27		log.Fatalf("Failed to load default English translation: %s", err)
28	}
29
30	// Try to load the specified language translations
31	if lang != "en" {
32		if err := loadTranslations(bundle, lang+".yaml"); err != nil {
33			// Try loading the base language if the specific locale fails
34			baseLang := strings.Split(lang, "-")[0]
35			if baseLang != lang { // Only attempt if baseLang is different from lang
36				log.Printf("Failed to load %s translation, trying base language %s: %s", lang, baseLang, err)
37				if err := loadTranslations(bundle, baseLang+".yaml"); err != nil {
38					log.Printf("Failed to load base language %s translation, falling back to English: %s", baseLang, err)
39				} else {
40					lang = baseLang
41				}
42			} else {
43				log.Printf("Failed to load %s translation, falling back to English: %s", lang, err)
44			}
45		}
46	}
47
48	// Create a localizer for the specified language
49	localizer = i18n.NewLocalizer(bundle, lang)
50}
51
52// loadTranslations loads translation files into the bundle
53func loadTranslations(bundle *i18n.Bundle, filename string) error {
54	data, err := localeFiles.ReadFile(filename)
55	if err != nil {
56		return err
57	}
58
59	// Must use bundle.ParseMessageFileBytes instead of LoadMessageFile for embedded data
60	_, err = bundle.ParseMessageFileBytes(data, filename)
61	if err != nil {
62		return err
63	}
64	return nil
65}
66
67// T translates a message ID to the current language
68func T(messageID string, templateData map[string]string) string {
69	result, err := localizer.Localize(&i18n.LocalizeConfig{
70		MessageID:    messageID,
71		TemplateData: templateData,
72	})
73	if err != nil {
74		log.Printf("Failed to localize message: %s", err)
75		return messageID + "*"
76	}
77	return result
78}
79
80// getPreferredLanguage determines the user's preferred language using go-locale
81func getPreferredLanguage() string {
82	lang, err := locale.GetLocale()
83	if err != nil {
84		log.Printf("Failed to get preferred language, defaulting to English: %s", err)
85		return "en"
86	}
87
88	// Normalize the language code
89	lang = strings.Split(lang, ".")[0] // Remove encoding part
90	lang = strings.ReplaceAll(lang, "_", "-")
91
92	return lang
93}
94