#!/usr/bin/env python3
"""
Add I18n.loadModule() calls to JS files that use I18n.t().
This ensures module translations are loaded before use.
"""

import re
from pathlib import Path

PROJECT_ROOT = Path(__file__).parent.parent
MODULES_DIR = PROJECT_ROOT / "app" / "modules"

# Pattern to find I18n.t('module.xxx') calls and extract module name
I18N_PATTERN = re.compile(r"I18n\.t\(['\"](\w+)\.")


def find_modules_used(content: str) -> set[str]:
    """Find all modules referenced in I18n.t() calls."""
    return set(I18N_PATTERN.findall(content))


def add_module_loading(js_file: Path):
    """Add I18n.loadModule() calls to a JS file."""
    content = js_file.read_text(encoding="utf-8")

    # Find modules used in this file
    modules = find_modules_used(content)
    if not modules:
        return False

    # Check if already has module loading
    if "I18n.loadModule(" in content:
        return False

    # Find the init() method and add loading there
    # Look for common patterns:
    # 1. init() { ... }
    # 2. async init() { ... }

    init_patterns = [
        # Pattern for "init() {" or "async init() {"
        (r"((?:async\s+)?init\s*\(\s*\)\s*\{)", "init"),
        # Pattern for "mounted() {" (Vue style)
        (r"(mounted\s*\(\s*\)\s*\{)", "mounted"),
    ]

    for pattern, method_name in init_patterns:
        match = re.search(pattern, content)
        if match:
            # Generate loading code
            load_calls = "\n".join(f"            await I18n.loadModule('{m}');" for m in sorted(modules))

            # If init is not async, we need to make it async
            full_match = match.group(1)
            if "async" not in full_match:
                # Make init async
                new_init = full_match.replace(f"{method_name}()", f"async {method_name}()")
                content = content.replace(full_match, new_init)
                full_match = new_init

            # Add loading after the opening brace
            insert_code = f"\n            // Load i18n translations\n{load_calls}\n"
            content = content.replace(full_match, full_match + insert_code)

            js_file.write_text(content, encoding="utf-8")
            return True

    # If no init found, add at file level (for simpler scripts)
    # This handles files that don't use Alpine components
    if "function " in content or "const " in content:
        # Find first function definition
        func_match = re.search(r"^(function\s+\w+\s*\([^)]*\)\s*\{)", content, re.MULTILINE)
        if func_match:
            load_calls = "\n".join(f"    await I18n.loadModule('{m}');" for m in sorted(modules))

            # Make function async if needed
            full_match = func_match.group(1)
            if "async" not in full_match:
                new_func = full_match.replace("function ", "async function ")
                content = content.replace(full_match, new_func)
                full_match = new_func

            insert_code = f"\n    // Load i18n translations\n{load_calls}\n"
            content = content.replace(full_match, full_match + insert_code)

            js_file.write_text(content, encoding="utf-8")
            return True

    return False


def main():
    print("=" * 70)
    print("Adding I18n.loadModule() to JS files")
    print("=" * 70)

    updated = 0
    skipped = 0

    # Find all JS files with I18n.t() calls
    for js_file in MODULES_DIR.rglob("*.js"):
        content = js_file.read_text(encoding="utf-8")
        if "I18n.t(" not in content:
            continue

        modules = find_modules_used(content)
        if not modules:
            continue

        rel_path = js_file.relative_to(PROJECT_ROOT)

        if add_module_loading(js_file):
            print(f"  Updated: {rel_path} (modules: {', '.join(sorted(modules))})")
            updated += 1
        else:
            print(f"  Skipped: {rel_path} (already has loading or no init method)")
            skipped += 1

    print()
    print(f"Updated: {updated} files")
    print(f"Skipped: {skipped} files")
    print("=" * 70)


if __name__ == "__main__":
    main()
