#!/usr/bin/env python3
"""
Translate missing strings in Localizable.xcstrings to all target languages.
Uses Google Translate (free, no API key needed).

Usage:
    pip install deep-translator
    python3 scripts/translate_xcstrings.py
"""

import json
import re
import sys
import time
from pathlib import Path

try:
    from deep_translator import GoogleTranslator
except ImportError:
    print("Please install deep-translator: pip install deep-translator")
    sys.exit(1)

XCSTRINGS_PATH = Path(__file__).parent.parent / "Feels" / "Localizable.xcstrings"
TARGET_LANGUAGES = {
    "de": "german",
    "es": "spanish",
    "fr": "french",
    "ja": "japanese",
    "ko": "korean",
    "pt-BR": "portuguese"
}

LANG_DISPLAY = {
    "de": "German",
    "es": "Spanish",
    "fr": "French",
    "ja": "Japanese",
    "ko": "Korean",
    "pt-BR": "Brazilian Portuguese"
}

# Strings that should not be translated
SKIP_PATTERNS = [
    "", " ", "  ", "   ", "-", "—", "·", "•", ">", "§",
    "12", "17", "20",
]


def get_english_value(string_data: dict, key: str) -> str | None:
    """Extract the English value for a string."""
    localizations = string_data.get("localizations", {})
    if "en" in localizations:
        en_loc = localizations["en"]
        if "stringUnit" in en_loc:
            return en_loc["stringUnit"].get("value")
    return key


def needs_translation(string_data: dict, lang: str) -> bool:
    """Check if a string needs translation for a given language."""
    localizations = string_data.get("localizations", {})
    if lang not in localizations:
        return True
    lang_data = localizations[lang]
    if "stringUnit" not in lang_data:
        return True
    state = lang_data["stringUnit"].get("state", "")
    return state not in ["translated"]


def should_skip(key: str, english_value: str) -> bool:
    """Check if a string should be skipped."""
    if not key.strip() or not english_value.strip():
        return True
    if key in SKIP_PATTERNS or english_value in SKIP_PATTERNS:
        return True
    stripped = english_value.strip()
    if stripped.startswith("%") and len(stripped) <= 10 and " " not in stripped:
        return True
    if "http://" in english_value or "https://" in english_value:
        return True
    return False


def protect_format_specifiers(text: str) -> tuple[str, dict]:
    """Replace format specifiers with placeholders to protect them during translation."""
    placeholders = {}
    counter = [0]

    def replace(match):
        placeholder = f"__FMT{counter[0]}__"
        placeholders[placeholder] = match.group(0)
        counter[0] += 1
        return placeholder

    # Match format specifiers: %@, %lld, %1$@, %2$lld, %.0f%%, etc.
    pattern = r'%(\d+\$)?[-+0 #]*(\d+)?(\.\d+)?(lld|ld|d|@|f|s|%%)'
    protected = re.sub(pattern, replace, text)
    return protected, placeholders


def restore_format_specifiers(text: str, placeholders: dict) -> str:
    """Restore format specifiers from placeholders."""
    for placeholder, original in placeholders.items():
        text = text.replace(placeholder, original)
    return text


def translate_string(text: str, target_lang: str) -> str | None:
    """Translate a single string, preserving format specifiers."""
    if not text.strip():
        return text

    # Protect format specifiers
    protected, placeholders = protect_format_specifiers(text)

    try:
        translator = GoogleTranslator(source='en', target=target_lang)
        translated = translator.translate(protected)

        if translated:
            # Restore format specifiers
            result = restore_format_specifiers(translated, placeholders)
            return result
        return None
    except Exception as e:
        print(f"    Translation error: {e}")
        return None


def main():
    print(f"Loading {XCSTRINGS_PATH}...")
    with open(XCSTRINGS_PATH, "r") as f:
        data = json.load(f)

    strings = data.get("strings", {})
    print(f"Found {len(strings)} total strings")

    # Find strings needing translation
    needs_work = []
    for key, string_data in strings.items():
        english_value = get_english_value(string_data, key)
        if not english_value or should_skip(key, english_value):
            continue
        missing_langs = [
            lang for lang in TARGET_LANGUAGES.keys()
            if needs_translation(string_data, lang)
        ]
        if missing_langs:
            needs_work.append((key, english_value, missing_langs))

    print(f"Found {len(needs_work)} strings needing translation")
    total_translations = sum(len(ml) for _, _, ml in needs_work)
    print(f"Total translations needed: {total_translations}")

    if not needs_work:
        print("All strings are already translated!")
        return

    total_translated = 0

    for i, (key, english, missing_langs) in enumerate(needs_work):
        print(f"\n[{i+1}/{len(needs_work)}] \"{english[:50]}{'...' if len(english) > 50 else ''}\"")

        if "localizations" not in strings[key]:
            strings[key]["localizations"] = {}

        for lang in missing_langs:
            google_lang = TARGET_LANGUAGES[lang]
            translated = translate_string(english, google_lang)

            if translated:
                strings[key]["localizations"][lang] = {
                    "stringUnit": {
                        "state": "translated",
                        "value": translated
                    }
                }
                total_translated += 1
                print(f"  {lang}: {translated[:60]}{'...' if len(translated) > 60 else ''}")
            else:
                print(f"  {lang}: FAILED")

            # Rate limiting to avoid getting blocked
            time.sleep(0.3)

        # Save progress every 20 strings
        if (i + 1) % 20 == 0:
            print(f"\n  Saving progress ({total_translated} translations)...")
            with open(XCSTRINGS_PATH, "w") as f:
                json.dump(data, f, indent=2, ensure_ascii=False)

    # Final save
    print(f"\nSaving {total_translated} translations...")
    with open(XCSTRINGS_PATH, "w") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)

    print("\n=== Summary ===")
    for lang, name in LANG_DISPLAY.items():
        count = sum(
            1 for s in strings.values()
            if s.get("localizations", {}).get(lang, {}).get("stringUnit", {}).get("state") == "translated"
        )
        total = len([k for k, v in strings.items() if not should_skip(k, get_english_value(v, k) or "")])
        pct = (count / total * 100) if total > 0 else 0
        print(f"  {name}: {count}/{total} ({pct:.0f}%)")

    print("\nDone!")


if __name__ == "__main__":
    main()
