"""
Helpers pour le formatage des Settings CMS.

Usage:
    from cms.helpers import format_setting, format_phone, format_email, format_url

    # Formatage automatique selon le type
    formatted = format_setting('site_phone')

    # Formatages specifiques
    phone = format_phone('+33 1 23 45 67 89')
    email = format_email('contact@example.com', link=True)
    url = format_url('https://example.com', text='Visiter')
"""
import re
from django.utils.safestring import mark_safe
from django.utils.html import escape


def get_setting_object(slug):
    """
    Recupere un objet Setting par son slug.

    Returns:
        Setting ou None
    """
    from cms.models import Setting
    try:
        return Setting.objects.select_related('type').get(slug=slug)
    except Setting.DoesNotExist:
        return None


def format_setting(slug, default='', custom_pattern=None):
    """
    Recupere et formate un setting.

    Args:
        slug: Cle du setting
        default: Valeur par defaut si non trouve
        custom_pattern: Pattern personnalise (optionnel)

    Returns:
        Valeur formatee ou default
    """
    setting = get_setting_object(slug)
    if not setting:
        return default

    if custom_pattern:
        return setting.get_formatted_value(custom_pattern)
    return setting.get_value()


# =============================================================================
# Formatages specifiques
# =============================================================================

def format_phone(value, link=True, country_code='+33'):
    """
    Formate un numero de telephone.

    Args:
        value: Numero de telephone
        link: Si True, retourne un lien tel:
        country_code: Code pays par defaut

    Returns:
        Numero formate (avec ou sans lien)
    """
    if not value:
        return ''

    # Nettoie le numero (garde uniquement chiffres et +)
    clean = re.sub(r'[^\d+]', '', str(value))

    # Ajoute le code pays si manquant
    if not clean.startswith('+'):
        if clean.startswith('0'):
            clean = country_code + clean[1:]
        else:
            clean = country_code + clean

    # Format d'affichage
    display = value

    if link:
        return mark_safe(f'<a href="tel:{clean}">{escape(display)}</a>')
    return display


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

    Args:
        value: Adresse email
        link: Si True, retourne un lien mailto:
        subject: Sujet pre-rempli (optionnel)
        css_class: Classe CSS pour le lien

    Returns:
        Email formate (avec ou sans lien)
    """
    if not value:
        return ''

    if link:
        href = f'mailto:{value}'
        if subject:
            href += f'?subject={escape(subject)}'
        class_attr = f' class="{css_class}"' if css_class else ''
        return mark_safe(f'<a href="{href}"{class_attr}>{escape(value)}</a>')
    return value


def format_url(value, text=None, new_tab=True, css_class=''):
    """
    Formate une URL.

    Args:
        value: URL
        text: Texte du lien (utilise l'URL si non fourni)
        new_tab: Si True, ouvre dans un nouvel onglet
        css_class: Classe CSS pour le lien

    Returns:
        URL formatee en lien HTML
    """
    if not value:
        return ''

    display = text or value
    target = ' target="_blank" rel="noopener noreferrer"' if new_tab else ''
    class_attr = f' class="{css_class}"' if css_class else ''

    return mark_safe(f'<a href="{escape(value)}"{target}{class_attr}>{escape(display)}</a>')


def format_currency(value, currency='EUR', symbol_position='after', decimal_places=2):
    """
    Formate une valeur monetaire.

    Args:
        value: Montant
        currency: Code devise (EUR, USD, etc.)
        symbol_position: 'before' ou 'after'
        decimal_places: Nombre de decimales

    Returns:
        Montant formate
    """
    if not value:
        return ''

    try:
        amount = float(value)
        formatted = f'{amount:,.{decimal_places}f}'.replace(',', ' ')

        symbols = {
            'EUR': '\u20ac',
            'USD': '$',
            'GBP': '\u00a3',
            'CHF': 'CHF',
        }
        symbol = symbols.get(currency, currency)

        if symbol_position == 'before':
            return f'{symbol}{formatted}'
        return f'{formatted} {symbol}'
    except (ValueError, TypeError):
        return str(value)


def format_address(lines, separator='<br>'):
    """
    Formate une adresse multi-lignes.

    Args:
        lines: Liste de lignes ou string avec retours a la ligne
        separator: Separateur HTML

    Returns:
        Adresse formatee
    """
    if not lines:
        return ''

    if isinstance(lines, str):
        lines = lines.split('\n')

    formatted = separator.join(escape(line.strip()) for line in lines if line.strip())
    return mark_safe(formatted)


def format_social_link(platform, username, icon=True):
    """
    Formate un lien vers un reseau social.

    Args:
        platform: Nom du reseau (facebook, twitter, linkedin, instagram, youtube)
        username: Nom d'utilisateur ou URL complete
        icon: Si True, affiche une icone

    Returns:
        Lien formate vers le profil
    """
    if not username:
        return ''

    base_urls = {
        'facebook': 'https://facebook.com/',
        'twitter': 'https://twitter.com/',
        'x': 'https://x.com/',
        'linkedin': 'https://linkedin.com/in/',
        'instagram': 'https://instagram.com/',
        'youtube': 'https://youtube.com/@',
        'github': 'https://github.com/',
    }

    platform_lower = platform.lower()

    # Si c'est deja une URL complete
    if username.startswith('http'):
        url = username
    else:
        base = base_urls.get(platform_lower, '')
        url = f'{base}{username}'

    icon_html = f'<i class="fab fa-{platform_lower}"></i> ' if icon else ''

    return mark_safe(
        f'<a href="{escape(url)}" target="_blank" rel="noopener noreferrer">'
        f'{icon_html}{escape(platform.capitalize())}</a>'
    )


# =============================================================================
# Helpers pour les templates
# =============================================================================

def setting_as_dict(slug):
    """
    Retourne un setting sous forme de dictionnaire.

    Utile pour passer a JavaScript ou serialiser.
    """
    setting = get_setting_object(slug)
    if not setting:
        return None

    return {
        'name': setting.name,
        'slug': setting.slug,
        'value': setting.value,
        'formatted_value': setting.get_value(),
        'has_image': bool(setting.image),
        'image_url': setting.image.url if setting.image else None,
        'type': setting.type.slug if setting.type else None,
    }


def get_settings_by_type(type_slug):
    """
    Recupere tous les settings d'un type donne.

    Args:
        type_slug: Slug du SettingType

    Returns:
        QuerySet de Settings
    """
    from cms.models import Setting
    return Setting.objects.filter(type__slug=type_slug).select_related('type')


def bulk_get_settings(*slugs):
    """
    Recupere plusieurs settings en une seule requete.

    Args:
        *slugs: Liste de slugs

    Returns:
        Dict {slug: setting_object}
    """
    from cms.models import Setting
    settings = Setting.objects.filter(slug__in=slugs).select_related('type')
    return {s.slug: s for s in settings}
