"""
Template tags pour le CMS.

Usage:
    {% load cms_tags %}

    {% get_setting 'site_email' as email %}
    {% get_menu 'header' as nav %}
    {% render_menu nav 'nav-class' %}
    {% render_section section %}
    {% setting_image 'logo' 'logo-class' 'Alt text' %}
"""
from django import template
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe

from cms.context_processors import get_setting as _get_setting, get_menu as _get_menu
from cms.models import Page, Section, Setting, PageSection, PageSectionFieldValue
from traduction.helpers import prefetch_translations

register = template.Library()


# =============================================================================
# Tags pour les Settings
# =============================================================================

@register.simple_tag(takes_context=True)
def get_setting(context, slug, default=''):
    """
    Recupere un parametre CMS par son slug.
    Utilise la langue courante de la request.

    Usage: {% get_setting 'site_email' as email %}
    """
    # Recuperer le code de la langue courante
    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_setting(slug, default, language_code=language_code)


@register.simple_tag
def setting_value(slug, default=''):
    """
    Retourne la valeur brute d'un parametre (sans formatage).

    Usage: {% setting_value 'phone' as phone %}
    """
    try:
        setting = Setting.objects.get(slug=slug)
        return setting.get_raw_value() or default
    except Setting.DoesNotExist:
        return default


@register.simple_tag
def setting_image(slug, css_class='', alt=''):
    """
    Affiche l'image d'un parametre.

    Usage: {% setting_image 'logo' 'logo-class' 'Site Logo' %}
    """
    try:
        setting = Setting.objects.get(slug=slug)
        if setting.image:
            return mark_safe(
                f'<img src="{setting.image.url}" class="{css_class}" alt="{alt or setting.name}" />'
            )
    except Setting.DoesNotExist:
        pass
    return ''


# =============================================================================
# Tags pour les Menus
# =============================================================================

@register.simple_tag(takes_context=True)
def get_menu(context, slug):
    """
    Recupere un menu par son slug avec tous ses elements.
    Utilise la langue courante de la request pour les traductions.

    Usage: {% get_menu 'header' as nav %}
    """
    # Recuperer le code de la langue courante
    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_menu(slug, language_code=language_code)


@register.inclusion_tag('cms/tags/menu.html', takes_context=True)
def render_menu(context, menu, css_class='', item_class='', link_class=''):
    """
    Affiche un menu complet avec ses elements imbriques.

    Usage: {% render_menu header_menu 'nav-menu' 'nav-item' 'nav-link' %}
    """
    if menu is None:
        return {
            'items': [],
            'css_class': css_class,
            'item_class': item_class,
            'link_class': link_class,
        }

    return {
        'menu': menu,
        'items': menu.get_root_items(),
        'css_class': css_class,
        'item_class': item_class,
        'link_class': link_class,
        'request': context.get('request'),
    }


@register.inclusion_tag('cms/tags/menu_items.html', takes_context=True)
def render_menu_items(context, items, item_class='', link_class='', depth=0):
    """
    Affiche une liste d'elements de menu (recursif pour les sous-menus).

    Usage: {% render_menu_items nav.get_root_items 'nav-item' 'nav-link' %}
    """
    return {
        'items': items,
        'item_class': item_class,
        'link_class': link_class,
        'depth': depth,
        'request': context.get('request'),
    }


# =============================================================================
# Tags pour les Pages et Sections
# =============================================================================

@register.simple_tag(takes_context=True)
def get_page(context, slug):
    """
    Recupere une page CMS par son slug.
    Prefetch les traductions pour la langue courante.

    Usage: {% get_page 'about' as about_page %}
    """
    from traduction.helpers import prefetch_translations

    try:
        page = Page.objects.select_related('template').get(slug=slug, is_active=True)

        # Recuperer le code de la langue courante
        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)

        # Prefetch les traductions
        prefetch_translations([page], language_code=language_code)
        return page
    except Page.DoesNotExist:
        return None


@register.simple_tag(takes_context=True)
def get_homepage(context):
    """
    Recupere la page d'accueil.
    Prefetch les traductions pour la langue courante.

    Usage: {% get_homepage as home %}
    """
    from traduction.helpers import prefetch_translations

    try:
        page = Page.objects.select_related('template').get(is_homepage=True, is_active=True)

        # Recuperer le code de la langue courante
        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)

        # Prefetch les traductions
        prefetch_translations([page], language_code=language_code)
        return page
    except Page.DoesNotExist:
        return None


@register.inclusion_tag('cms/tags/section.html', takes_context=True)
def render_section(context, section, extra_class=''):
    """
    Affiche une section en utilisant son template.

    Usage: {% render_section section 'my-custom-class' %}
    """
    return {
        'section': section,
        'extra_class': extra_class,
        'request': context.get('request'),
    }


@register.simple_tag(takes_context=True)
def include_section(context, section):
    """
    Inclut le template d'une section directement.

    Usage: {% include_section section %}
    """
    if section and hasattr(section, 'get_template_path'):
        try:
            # Recuperer le code de langue
            request = context.get('request')
            language_code = None
            if request:
                language_code = getattr(request, 'current_language_code', None)

            # Traduire la section
            prefetch_translations([section], language_code=language_code)

            # Construire le contexte en incluant le contexte parent
            section_context = context.flatten()
            section_context['section'] = section
            return render_to_string(
                section.get_template_path(),
                section_context,
                request=request
            )
        except Exception as e:
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f"Erreur inclusion section {section.name}: {e}")
            return f'<!-- Erreur section {section.name}: {e} -->'
    return ''


# =============================================================================
# Tags pour les Menus - Helpers
# =============================================================================

@register.filter
def get_item(dictionary, key):
    """
    Recupere une valeur dans un dictionnaire par cle.

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


@register.filter
def menu_item_attrs(item):
    """
    Genere les attributs HTML pour un lien de menu.

    Usage: <a href="{{ item.get_url }}" {{ item|menu_item_attrs }}>
    """
    attrs = []

    if item.open_in_new_tab:
        attrs.append('target="_blank"')
        attrs.append('rel="noopener noreferrer"')

    if item.has_children():
        attrs.append('aria-haspopup="true"')
        attrs.append('aria-expanded="false"')

    return mark_safe(' '.join(attrs))


@register.filter
def split(value, separator=','):
    """
    Divise une chaine en liste.

    Usage:
        {% for item in value|split %}  {# par defaut: virgule #}
        {% for item in value|split:" " %}  {# par espace #}
    """
    if value:
        return [item.strip() for item in str(value).split(separator) if item.strip()]
    return []


@register.simple_tag(takes_context=True)
def is_active_menu_item(context, item):
    """
    Verifie si un element de menu correspond a la page courante.

    Usage: {% is_active_menu_item item as is_active %}
    """
    request = context.get('request')
    if not request:
        return False

    current_path = request.path
    item_url = item.get_url()

    if item_url == current_path:
        return True

    # Verifie si le chemin courant commence par l'URL de l'item
    if item_url and item_url != '/' and current_path.startswith(item_url):
        return True

    return False


@register.simple_tag(takes_context=True)
def menu_item_class(context, item, active_class='active', has_children_class='has-dropdown'):
    """
    Retourne les classes CSS pour un element de menu.

    Usage: <li class="{{ menu_item_class item 'active' 'dropdown' }}">
    """
    classes = []

    request = context.get('request')
    if request:
        current_path = request.path
        item_url = item.get_url()
        if item_url == current_path or (item_url != '/' and current_path.startswith(item_url)):
            classes.append(active_class)

    if item.has_children():
        classes.append(has_children_class)

    return ' '.join(classes)


# =============================================================================
# Tags pour les Keywords
# =============================================================================

@register.simple_tag
def get_keywords(obj):
    """
    Recupere les mots-cles associes a un objet.

    Usage: {% get_keywords page as keywords %}
    """
    from cms.models import KeywordAssignment
    return KeywordAssignment.get_keywords_for_object(obj)


@register.inclusion_tag('cms/tags/keywords.html')
def render_keywords(obj, css_class='', separator=', '):
    """
    Affiche les mots-cles d'un objet.

    Usage: {% render_keywords page 'keyword-list' %}
    """
    from cms.models import KeywordAssignment
    keywords = KeywordAssignment.get_keywords_for_object(obj)
    return {
        'keywords': keywords,
        'css_class': css_class,
        'separator': separator,
    }


@register.simple_tag
def get_objects_with_keyword(keyword_name):
    """
    Recupere tous les objets ayant un mot-cle specifique.

    Usage: {% get_objects_with_keyword 'python' as python_objects %}
    """
    from cms.models import KeywordAssignment
    return KeywordAssignment.get_objects_with_keyword(keyword_name)


# =============================================================================
# Tags pour le Formatage
# =============================================================================

@register.simple_tag
def format_phone(value, link=True):
    """
    Formate un numero de telephone.

    Usage: {% format_phone '+33 1 23 45 67 89' %}
           {% format_phone phone_number link=False %}
    """
    from cms.helpers import format_phone as _format_phone
    return _format_phone(value, link=link)


@register.simple_tag
def format_email(value, link=True, subject=''):
    """
    Formate une adresse email.

    Usage: {% format_email 'contact@example.com' %}
           {% format_email email subject='Demande info' %}
    """
    from cms.helpers import format_email as _format_email
    return _format_email(value, link=link, subject=subject)


@register.simple_tag
def format_url(value, text='', new_tab=True):
    """
    Formate une URL en lien cliquable.

    Usage: {% format_url 'https://example.com' %}
           {% format_url website text='Visiter le site' %}
    """
    from cms.helpers import format_url as _format_url
    return _format_url(value, text=text or None, new_tab=new_tab)


@register.simple_tag
def format_currency(value, currency='EUR'):
    """
    Formate une valeur monetaire.

    Usage: {% format_currency '1500' %}
           {% format_currency price currency='USD' %}
    """
    from cms.helpers import format_currency as _format_currency
    return _format_currency(value, currency=currency)


@register.simple_tag
def format_address(value):
    """
    Formate une adresse multi-lignes.

    Usage: {% format_address address_text %}
    """
    from cms.helpers import format_address as _format_address
    return _format_address(value)


@register.simple_tag
def format_social(platform, username):
    """
    Formate un lien vers un reseau social.

    Usage: {% format_social 'twitter' 'username' %}
           {% format_social 'linkedin' linkedin_url %}
    """
    from cms.helpers import format_social_link
    return format_social_link(platform, username)


@register.simple_tag
def setting_formatted(slug, pattern=''):
    """
    Recupere un setting avec formatage personnalise.

    Usage: {% setting_formatted 'price' pattern='<strong>{value}</strong> EUR' %}
    """
    from cms.helpers import format_setting
    return mark_safe(format_setting(slug, custom_pattern=pattern or None))


# =============================================================================
# Tags pour les Champs Personnalises de Section
# =============================================================================

@register.simple_tag(takes_context=True)
def get_section_field(context, page_section, field_slug, default=''):
    """
    Recupere la valeur d'un champ personnalise pour un PageSection.
    Supporte les traductions automatiquement.

    Usage: {% get_section_field page_section 'button_text' 'En savoir plus' as btn_text %}
    """
    if not page_section:
        return default

    # Recuperer le code de langue depuis la requete
    request = context.get('request')
    language_code = None
    if request:
        language_code = getattr(request, 'current_language_code', None)

    if hasattr(page_section, 'get_field_value'):
        return page_section.get_field_value(field_slug, default, language_code=language_code)
    return default


@register.simple_tag(takes_context=True)
def get_section_fields(context, page_section):
    """
    Recupere tous les champs personnalises sous forme de dict.
    Supporte les traductions automatiquement.

    Usage: {% get_section_fields page_section as fields %}
           {{ fields.button_text }}
    """
    if not page_section:
        return {}

    # Recuperer le code de langue depuis la requete
    request = context.get('request')
    language_code = None
    if request:
        language_code = getattr(request, 'current_language_code', None)

    if hasattr(page_section, 'get_all_field_values'):
        return page_section.get_all_field_values(language_code=language_code)
    return {}


@register.inclusion_tag('cms/tags/section_field_image.html')
def section_field_image(page_section, field_slug, css_class='', alt=''):
    """
    Affiche une image de champ personnalise.

    Usage: {% section_field_image page_section 'background_image' 'bg-img' 'Image de fond' %}
    """
    image = None
    if page_section:
        try:
            fv = page_section.field_values.select_related('field').get(
                field__slug=field_slug
            )
            image = fv.image_value
        except PageSectionFieldValue.DoesNotExist:
            pass

    return {
        'image': image,
        'css_class': css_class,
        'alt': alt,
    }


@register.simple_tag(takes_context=True)
def include_section_with_fields(context, page_section):
    """
    Inclut le template d'une section avec ses champs personnalises.

    Usage: {% include_section_with_fields page_section %}

    Dans le template de section, les variables disponibles sont:
    - section: l'objet Section
    - page_section: l'objet PageSection
    - fields: dict des valeurs de champs {slug: valeur}
    - Plus toutes les variables du contexte parent (map_settings, latest_news, etc.)
    """
    if not page_section:
        return ''

    section = page_section.section
    if section and hasattr(section, 'get_template_path'):
        try:
            # Recuperer le code de langue depuis la requete
            request = context.get('request')
            language_code = None
            if request:
                language_code = getattr(request, 'current_language_code', None)

            # Traduire la section
            prefetch_translations([section], language_code=language_code)

            # Construire le contexte en incluant le contexte parent
            section_context = context.flatten()
            section_context['section'] = section
            section_context['page_section'] = page_section
            section_context['fields'] = page_section.get_all_field_values(language_code=language_code)
            return render_to_string(
                section.get_template_path(),
                section_context,
                request=request
            )
        except Exception as e:
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f"Erreur inclusion section {section.name}: {e}")
            return f'<!-- Erreur section {section.name}: {e} -->'
    return ''
