"""
Template tags pour les traductions

Utilisation:
    {% load traduction_tags %}

    {# Avec prefetch (recommande - utilise {{ article.title }} directement) #}
    {{ article.title }}

    {# Sans prefetch - utilise les tags #}
    {{ article|translate:'title' }}
    {% trans article 'title' %}
    {% get_translation article 'title' as title %}
"""

from django import template
from django.utils.safestring import mark_safe

from traduction.helpers import (
    get_translated_value,
    TRANSLATIONS_PREFETCHED_KEY,
)
from traduction.models import Language

register = template.Library()


@register.filter(takes_context=False)
def translate(obj, field):
    """
    Filtre pour traduire un champ

    Usage: {{ object|translate:'field_name' }}

    Note: Si l'objet a ete prefetche via TranslatedViewMixin ou prefetch_translations(),
    la valeur du champ est deja traduite et ce filtre retourne simplement l'attribut.
    Sinon, il fait une requete pour recuperer la traduction.
    """
    if not obj:
        return ''

    # Si prefetche, le champ contient deja la traduction
    if getattr(obj, TRANSLATIONS_PREFETCHED_KEY, False):
        return getattr(obj, field, '')

    # Recuperer la langue courante depuis le thread local ou la session
    from django.utils import translation
    lang_code = translation.get_language() or 'fr'

    # Si c'est le francais (langue par defaut), retourner la valeur originale
    if lang_code == 'fr':
        return getattr(obj, field, '')

    return get_translated_value(obj, field, language_code=lang_code, fallback=True)


@register.filter
def translate_lang(obj, args):
    """
    Filtre pour traduire un champ dans une langue specifique

    Usage: {{ object|translate_lang:'field_name:en' }}
    """
    if not obj:
        return ''

    parts = args.split(':')
    field = parts[0]
    language_code = parts[1] if len(parts) > 1 else None

    return get_translated_value(obj, field, language_code=language_code, fallback=True)


@register.simple_tag(takes_context=True)
def get_translation(context, obj, field, language_code=None):
    """
    Tag pour recuperer une traduction avec la langue de la session

    Usage:
        {% get_translation article 'title' as title %}
        {% get_translation article 'title' 'en' as title_en %}

    Note: Si l'objet a ete prefetche, retourne directement la valeur du champ.
    """
    if not obj:
        return ''

    # Si prefetche et pas de langue specifique, retourner directement
    if getattr(obj, TRANSLATIONS_PREFETCHED_KEY, False) and language_code is None:
        return getattr(obj, field, '')

    if language_code is None:
        # Essayer de recuperer depuis le contexte
        language_code = context.get('current_language_code')
        if not language_code:
            request = context.get('request')
            if request:
                language_code = getattr(request, 'current_language_code', None)

    return get_translated_value(obj, field, language_code=language_code, fallback=True)


@register.simple_tag(takes_context=True)
def trans(context, obj, field):
    """
    Tag simplifie pour traduire un champ avec la langue courante

    Usage: {% trans article 'title' %}

    Note: Si l'objet a ete prefetche via TranslatedViewMixin ou prefetch_translations(),
    retourne directement la valeur du champ (deja traduite).
    """
    if not obj:
        return ''

    # Si prefetche, retourner directement le champ (deja traduit)
    if getattr(obj, TRANSLATIONS_PREFETCHED_KEY, False):
        return getattr(obj, field, '')

    language_code = context.get('current_language_code')
    if not language_code:
        request = context.get('request')
        if request:
            language_code = getattr(request, 'current_language_code', None)

    return get_translated_value(obj, field, language_code=language_code, fallback=True)


@register.simple_tag
def get_languages():
    """
    Retourne toutes les langues actives

    Usage: {% get_languages as languages %}
    """
    return Language.get_active_languages()


@register.simple_tag
def get_default_language():
    """
    Retourne la langue par defaut

    Usage: {% get_default_language as default_lang %}
    """
    return Language.get_default()


@register.simple_tag(takes_context=True)
def current_language(context):
    """
    Retourne la langue courante

    Usage: {% current_language as lang %}
    """
    request = context.get('request')
    if request:
        return getattr(request, 'current_language', None)
    return Language.get_default()


@register.simple_tag(takes_context=True)
def current_language_code(context):
    """
    Retourne le code de la langue courante

    Usage: {% current_language_code as lang_code %}
    """
    request = context.get('request')
    if request:
        return getattr(request, 'current_language_code', 'fr')
    default = Language.get_default()
    return default.code if default else 'fr'


@register.inclusion_tag('traduction/language_selector.html', takes_context=True)
def language_selector(context):
    """
    Affiche un selecteur de langue

    Usage: {% language_selector %}
    """
    request = context.get('request')
    current_code = 'fr'
    if request:
        current_code = getattr(request, 'current_language_code', 'fr')

    return {
        'languages': Language.get_active_languages(),
        'current_language_code': current_code,
        'request': request,
    }


@register.filter
def get_item(dictionary, key):
    """
    Recupere un element d'un dictionnaire

    Usage: {{ dict|get_item:key }}
    """
    if dictionary is None:
        return None
    return dictionary.get(key)


@register.filter
def get_attr(obj, attr):
    """
    Recupere un attribut d'un objet

    Usage: {{ object|get_attr:'attribute_name' }}
    """
    if obj is None:
        return None
    return getattr(obj, attr, None)


@register.simple_tag(takes_context=True)
def trans_text(context, fr_text, en_text=None, de_text=None):
    """
    Tag pour traduire un texte statique

    Usage: {% trans_text 'Bonjour' 'Hello' 'Hallo' %}

    Arguments:
        fr_text: Texte en francais (par defaut)
        en_text: Texte en anglais (optionnel)
        de_text: Texte en allemand (optionnel)

    Si la traduction n'existe pas pour la langue courante, retourne le texte francais.
    """
    from django.utils import translation
    lang_code = translation.get_language() or 'fr'

    translations = {
        'fr': fr_text,
        'en': en_text or fr_text,
        'de': de_text or fr_text,
    }

    return translations.get(lang_code, fr_text)
