package i18n

import (
	"fmt"
	"regexp"

	systemService "be.ems/src/modules/system/service"
)

// localeItem 国际化数据项
type localeItem struct {
	Key   string `json:"key"`
	Value string `json:"value"`
	Code  string `json:"code"`
}

// localeMap 国际化数据组
var localeMap = make(map[string][]localeItem)

// ClearLocaleData 清空国际化数据
func ClearLocaleData() {
	localeMap = make(map[string][]localeItem)
}

// LoadLocaleData 加载国际化数据
func LoadLocaleData(language string) []localeItem {
	dictType := fmt.Sprintf("i18n_%s", language)
	dictTypeList := systemService.NewSysDictTypeImpl.DictDataCache(dictType)
	localeData := []localeItem{}
	for _, v := range dictTypeList {
		localeData = append(localeData, localeItem{
			Key:   v.DictLabel,
			Value: v.DictValue,
			Code:  v.DictCode,
		})
	}
	localeMap[language] = localeData
	return localeData
}

// UpdateKeyValue 更新键对应的值
func UpdateKeyValue(language, key, value string) bool {
	arr, ok := localeMap[language]
	if !ok || len(arr) == 0 {
		arr = LoadLocaleData(language)
	}

	code := ""
	if key == "" {
		return false
	}
	for _, v := range arr {
		if v.Key == key {
			code = v.Code
			break
		}
	}

	// 更新字典数据
	sysDictDataService := systemService.NewSysDictDataImpl
	item := sysDictDataService.SelectDictDataByCode(code)
	if item.DictCode == code && item.DictLabel == key {
		item.DictValue = value
		row := sysDictDataService.UpdateDictData(item)
		if row > 0 {
			delete(localeMap, language)
			return true
		}
	}
	return false
}

// TKey 翻译键
func TKey(language, key string) string {
	value := key
	if key == "" {
		return value
	}
	arr, ok := localeMap[language]
	if !ok || len(arr) == 0 {
		arr = LoadLocaleData(language)
	}

	for _, v := range arr {
		if v.Key == key {
			value = v.Value
			break
		}
	}
	return value
}

// TTemplate 翻译模板字符串
func TTemplate(language, key string, params map[string]any) string {
	templateString := TKey(language, key)

	re := regexp.MustCompile("{(.*?)}")
	result := re.ReplaceAllStringFunc(templateString, func(match string) string {
		key := match[1 : len(match)-1]
		if val, ok := params[key]; ok {
			return fmt.Sprint(val)
		}
		return match
	})

	return result
}
