package i18n

import (
	"sync"
	"testing"
)

func TestTranslator_New(t *testing.T) {
	tr := New()
	if tr.Lang() != DefaultLang {
		t.Errorf("default lang = %q, want %q", tr.Lang(), DefaultLang)
	}
}

func TestTranslator_SetLang_Get(t *testing.T) {
	tr := New()
	tr.SetLang("en")
	if tr.Lang() != "en" {
		t.Errorf("Lang = %q, want %q", tr.Lang(), "en")
	}
	tr.SetLang("zh-CN")
	if tr.Lang() != "zh-CN" {
		t.Errorf("Lang = %q, want %q", tr.Lang(), "zh-CN")
	}
	tr.SetLang("ja")
	if tr.Lang() != "ja" {
		t.Errorf("Lang = %q, want %q", tr.Lang(), "ja")
	}
}

func TestTranslator_RegisterAndGet(t *testing.T) {
	tr := New()
	tr.Register("en", map[string]string{
		"greeting": "Hello",
		"farewell": "Goodbye",
	})
	tr.Register("zh-CN", map[string]string{
		"greeting": "你好",
	})

	if got := tr.Get("greeting"); got != "你好" {
		t.Errorf("Get(greeting) with zh-CN = %q, want %q", got, "你好")
	}

	tr.SetLang("en")
	if got := tr.Get("greeting"); got != "Hello" {
		t.Errorf("Get(greeting) with en = %q, want %q", got, "Hello")
	}
}

func TestTranslator_Get_WithFormat(t *testing.T) {
	tr := New()
	tr.Register("en", map[string]string{
		"greeting": "Hello, %s!",
	})

	tr.SetLang("en")
	if got := tr.Get("greeting", "World"); got != "Hello, World!" {
		t.Errorf("Get(greeting, World) = %q, want %q", got, "Hello, World!")
	}
}

func TestTranslator_Get_Fallback(t *testing.T) {
	tr := New()
	tr.Register(DefaultLang, map[string]string{
		"common": "common value",
	})

	tr.SetLang("nonexistent")
	if got := tr.Get("common"); got != "common value" {
		t.Errorf("Get(common) with nonexistent lang should fallback to %q, got %q", "common value", got)
	}
}

func TestTranslator_Get_NotFound(t *testing.T) {
	tr := New()
	if got := tr.Get("nonexistent_key"); got != "nonexistent_key" {
		t.Errorf("Get(nonexistent_key) should return key itself, got %q", got)
	}
}

func TestTranslator_Register_Overwrite(t *testing.T) {
	tr := New()
	tr.Register("en", map[string]string{"key": "old"})
	tr.Register("en", map[string]string{"key": "new"})

	tr.SetLang("en")
	if got := tr.Get("key"); got != "new" {
		t.Errorf("Get(key) after overwrite = %q, want %q", got, "new")
	}
}

func TestTranslator_ConcurrentAccess(t *testing.T) {
	tr := New()
	tr.Register("en", map[string]string{"key": "value %d"})

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(2)
		go func(n int) {
			defer wg.Done()
			_ = tr.Get("key", n)
		}(i)
		go func() {
			defer wg.Done()
			tr.SetLang("en")
		}()
	}
	wg.Wait()
}

func TestGlobalTranslator(t *testing.T) {
	SetLang("en")
	if Lang() != "en" {
		t.Errorf("global Lang() = %q, want %q", Lang(), "en")
	}

	Register("test-lang", map[string]string{"test_key": "test_value"})
	SetLang("test-lang")
	if got := Get("test_key"); got != "test_value" {
		t.Errorf("global Get(test_key) = %q, want %q", got, "test_value")
	}
}
