"""Multi-language i18n endpoint tests for RBS REGAL Business Suite."""
import os
import re
import requests
import pytest

BASE_URL = os.environ.get("REACT_APP_BACKEND_URL", "https://offline-billing-pro-2.preview.emergentagent.com").rstrip("/")

EXPECTED_CODES = {"en", "hi", "gu", "mr", "pa", "bn", "ta", "te", "kn", "ml", "or", "ur", "kok"}


# ----- /api/i18n/languages (public) -----
class TestLanguages:
    def test_list_languages(self):
        r = requests.get(f"{BASE_URL}/api/i18n/languages", timeout=30)
        assert r.status_code == 200, r.text
        data = r.json()
        assert isinstance(data, list)
        assert len(data) == 13, f"Expected 13 languages, got {len(data)}"
        codes = {row["code"] for row in data}
        assert codes == EXPECTED_CODES, f"Mismatch: {codes ^ EXPECTED_CODES}"
        for row in data:
            assert {"code", "name", "native", "dir", "flag"} <= set(row.keys()), row
            assert row["dir"] in ("ltr", "rtl")
        ur = next(row for row in data if row["code"] == "ur")
        assert ur["dir"] == "rtl"


# ----- /api/i18n/translate -----
class TestTranslate:
    SAMPLE = ["Total Sales", "New Invoice", "Customers", "Stock", "Dashboard"]

    def test_translate_gujarati(self, admin_session):
        # Cache-bust: append a unique nonce so we definitely exercise the LLM path
        import uuid
        nonce = uuid.uuid4().hex[:6]
        texts = [f"{t} {nonce}" for t in self.SAMPLE]
        r = admin_session.post(f"{BASE_URL}/api/i18n/translate",
                               json={"lang": "gu", "texts": texts, "use_cache": True},
                               timeout=120)
        assert r.status_code == 200, r.text
        data = r.json()
        assert data["lang"] == "gu"
        assert "translations" in data
        # All five sample strings should have a translation
        for t in texts:
            assert t in data["translations"]
        # At least some should come from LLM (since cache-busted) — or fallback to source if LLM fails
        assert data["from_llm"] + data["from_cache"] >= len(texts) - 1
        # Verify Gujarati script presence in at least one translation when LLM succeeded
        gu_chars = re.compile(r"[\u0A80-\u0AFF]")
        translated_count = sum(1 for t in texts if gu_chars.search(data["translations"][t] or ""))
        # Soft-assert: warn but don't crash if LLM didn't respond
        if data["from_llm"] > 0:
            assert translated_count >= 1, f"No Gujarati script found in {data['translations']}"

    def test_translate_urdu_rtl_script(self, admin_session):
        texts = ["New Invoice", "Customers", "GST", "WhatsApp", "Save"]
        r = admin_session.post(f"{BASE_URL}/api/i18n/translate",
                               json={"lang": "ur", "texts": texts, "use_cache": True},
                               timeout=120)
        assert r.status_code == 200, r.text
        data = r.json()
        assert data["lang"] == "ur"
        for t in texts:
            assert t in data["translations"]
        # Brand names should remain in Latin
        assert "GST" in data["translations"]["GST"] or data["translations"]["GST"] == "GST"
        # At least one Arabic-script translation should exist
        ar_chars = re.compile(r"[\u0600-\u06FF]")
        has_arabic = any(ar_chars.search(v or "") for v in data["translations"].values())
        # Soft: only enforce if LLM produced fresh translations
        if data["from_llm"] > 0 or data["from_cache"] > 0:
            assert has_arabic, f"No Arabic script found in Urdu translations: {data['translations']}"

    def test_cache_hit_on_repeat(self, admin_session):
        texts = ["Dashboard", "Reports", "Settings"]
        # First call — warm the cache
        r1 = admin_session.post(f"{BASE_URL}/api/i18n/translate",
                                json={"lang": "gu", "texts": texts, "use_cache": True},
                                timeout=120)
        assert r1.status_code == 200, r1.text
        # Second call — should be all cache
        r2 = admin_session.post(f"{BASE_URL}/api/i18n/translate",
                                json={"lang": "gu", "texts": texts, "use_cache": True},
                                timeout=30)
        assert r2.status_code == 200, r2.text
        d2 = r2.json()
        assert d2["from_llm"] == 0, f"Expected 0 LLM calls on cache hit, got {d2['from_llm']}"
        assert d2["from_cache"] >= len(texts), f"Expected cache hits >= {len(texts)}, got {d2['from_cache']}"

    def test_unsupported_language(self, admin_session):
        r = admin_session.post(f"{BASE_URL}/api/i18n/translate",
                               json={"lang": "xx", "texts": ["Hello"], "use_cache": True},
                               timeout=30)
        assert r.status_code == 400, r.text

    def test_english_identity(self, admin_session):
        r = admin_session.post(f"{BASE_URL}/api/i18n/translate",
                               json={"lang": "en", "texts": ["Hello", "World"], "use_cache": True},
                               timeout=30)
        assert r.status_code == 200
        d = r.json()
        assert d["translations"] == {"Hello": "Hello", "World": "World"}


# ----- /api/i18n/set-user-lang + /me -----
class TestUserLang:
    def test_set_and_get_user_lang(self, admin_session):
        # Set Marathi
        r = admin_session.post(f"{BASE_URL}/api/i18n/set-user-lang",
                               json={"lang": "mr"}, timeout=30)
        assert r.status_code == 200, r.text
        assert r.json()["lang"] == "mr"

        # Fetch — verify persistence
        r2 = admin_session.get(f"{BASE_URL}/api/i18n/me", timeout=30)
        assert r2.status_code == 200, r2.text
        assert r2.json()["lang"] == "mr"

        # Restore to English
        r3 = admin_session.post(f"{BASE_URL}/api/i18n/set-user-lang",
                                json={"lang": "en"}, timeout=30)
        assert r3.status_code == 200

    def test_set_invalid_lang(self, admin_session):
        r = admin_session.post(f"{BASE_URL}/api/i18n/set-user-lang",
                               json={"lang": "zz"}, timeout=30)
        assert r.status_code == 400


# ----- /api/i18n/ai-system-prompt/{lang} -----
class TestAiSystemPrompt:
    def test_english_prompt(self):
        r = requests.get(f"{BASE_URL}/api/i18n/ai-system-prompt/en", timeout=30)
        assert r.status_code == 200
        d = r.json()
        assert d["lang"] == "en"
        assert "English" in d["system_prompt"]

    def test_hindi_prompt(self):
        r = requests.get(f"{BASE_URL}/api/i18n/ai-system-prompt/hi", timeout=30)
        assert r.status_code == 200
        d = r.json()
        assert d["lang"] == "hi"
        assert d["native_name"] == "हिन्दी"

    def test_gujarati_prompt(self):
        r = requests.get(f"{BASE_URL}/api/i18n/ai-system-prompt/gu", timeout=30)
        assert r.status_code == 200
        d = r.json()
        assert d["lang"] == "gu"
        assert "Gujarati" in d["system_prompt"]
        assert d["native_name"] == "ગુજરાતી"

    def test_invalid_lang_falls_back_english(self):
        r = requests.get(f"{BASE_URL}/api/i18n/ai-system-prompt/xx", timeout=30)
        assert r.status_code == 200
        assert r.json()["lang"] == "en"
