from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from traduction.mixins import TranslatableMixin


class Language(models.Model):
    """Modele pour gerer les langues disponibles"""
    code = models.CharField(
        'Code langue',
        max_length=10,
        unique=True,
        help_text='Code ISO (ex: fr, en, de, es)'
    )
    name = models.CharField('Nom', max_length=100)
    native_name = models.CharField(
        'Nom natif',
        max_length=100,
        blank=True,
        help_text='Nom dans la langue elle-meme (ex: Francais, English)'
    )
    flag_code = models.CharField(
        'Code drapeau',
        max_length=10,
        blank=True,
        help_text='Code pays pour le drapeau (ex: fr, gb, de)'
    )
    is_default = models.BooleanField(
        'Langue par defaut',
        default=False,
        help_text='Une seule langue peut etre par defaut'
    )
    is_active = models.BooleanField('Active', default=True)
    order = models.PositiveIntegerField('Ordre', default=0)

    class Meta:
        verbose_name = 'Langue'
        verbose_name_plural = 'Langues'
        ordering = ['order', 'name']

    def __str__(self):
        return f"{self.name} ({self.code})"

    def save(self, *args, **kwargs):
        # S'assurer qu'une seule langue est par defaut
        if self.is_default:
            Language.objects.filter(is_default=True).exclude(pk=self.pk).update(is_default=False)
        # Si c'est la premiere langue, la mettre par defaut
        if not self.pk and not Language.objects.exists():
            self.is_default = True
        super().save(*args, **kwargs)

    @classmethod
    def get_default(cls):
        """Retourne la langue par defaut"""
        return cls.objects.filter(is_default=True, is_active=True).first()

    @classmethod
    def get_active_languages(cls):
        """Retourne toutes les langues actives"""
        return cls.objects.filter(is_active=True).order_by('order', 'name')


class Dictionnaire(models.Model):
    """Modele pour stocker les traductions de tous les contenus"""
    content_type = models.ForeignKey(
        ContentType,
        on_delete=models.CASCADE,
        verbose_name='Type de contenu'
    )
    object_id = models.PositiveIntegerField('ID objet')
    content_object = GenericForeignKey('content_type', 'object_id')

    field = models.CharField(
        'Champ',
        max_length=100,
        help_text='Nom du champ traduit'
    )
    language = models.ForeignKey(
        Language,
        on_delete=models.CASCADE,
        related_name='translations',
        verbose_name='Langue'
    )
    translation = models.TextField('Traduction')

    created_at = models.DateTimeField('Cree le', auto_now_add=True)
    updated_at = models.DateTimeField('Modifie le', auto_now=True)

    class Meta:
        verbose_name = 'Traduction'
        verbose_name_plural = 'Dictionnaire'
        ordering = ['content_type', 'object_id', 'field', 'language']
        unique_together = ['content_type', 'object_id', 'field', 'language']
        indexes = [
            models.Index(fields=['content_type', 'object_id']),
            models.Index(fields=['content_type', 'object_id', 'field']),
        ]

    def __str__(self):
        return f"{self.content_type.model}.{self.field} [{self.language.code}]"

    @classmethod
    def get_translation(cls, obj, field, language_code):
        """Recupere une traduction pour un objet et un champ donnes"""
        content_type = ContentType.objects.get_for_model(obj)
        try:
            translation = cls.objects.get(
                content_type=content_type,
                object_id=obj.pk,
                field=field,
                language__code=language_code,
                language__is_active=True
            )
            return translation.translation
        except cls.DoesNotExist:
            return None

    @classmethod
    def get_translations_for_object(cls, obj, language_code=None):
        """Recupere toutes les traductions pour un objet"""
        content_type = ContentType.objects.get_for_model(obj)
        qs = cls.objects.filter(
            content_type=content_type,
            object_id=obj.pk,
            language__is_active=True
        )
        if language_code:
            qs = qs.filter(language__code=language_code)
        return qs

    @classmethod
    def set_translation(cls, obj, field, language, translation_text):
        """Definit ou met a jour une traduction"""
        content_type = ContentType.objects.get_for_model(obj)
        if isinstance(language, str):
            language = Language.objects.get(code=language)

        translation, created = cls.objects.update_or_create(
            content_type=content_type,
            object_id=obj.pk,
            field=field,
            language=language,
            defaults={'translation': translation_text}
        )
        return translation

    @classmethod
    def delete_translations_for_object(cls, obj):
        """Supprime toutes les traductions pour un objet"""
        content_type = ContentType.objects.get_for_model(obj)
        cls.objects.filter(
            content_type=content_type,
            object_id=obj.pk
        ).delete()

class Traducteur(TranslatableMixin, models.Model):
    key = models.CharField('Cle', max_length=100, unique=True)
    value = models.TextField('Traduction', blank=True, null=True)
    created_at = models.DateTimeField('Cree le', auto_now_add=True)
    updated_at = models.DateTimeField('Modifie le', auto_now=True)

    class Meta:
        verbose_name = 'Traducteur'
        verbose_name_plural = 'Traducteurs'

    def get_value(self):
        value = self.get_translated('value') or self.value
        return f"{value}"

    def __str__(self):
        return f"{self.key} = {self.get_value()}"