from django.db import models
from django.conf import settings
from django.utils import timezone
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from modelcluster.fields import ParentalKey, ParentalManyToManyField
from wagtail.models import Page, Orderable, Locale
from wagtail.fields import RichTextField, StreamField
from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel
from wagtail.documents.models import Document
from wagtail.blocks import StructBlock, RichTextBlock, URLBlock, CharBlock
from wagtail.snippets.models import register_snippet

from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.db import connection

EDITOR_COMPLETO = [
    'h2', 'h3', 'h4', 'bold', 'italic', 'table', 
    'font-size', 'font-family', 'link', 'document-link', 
    'ol', 'ul', 'hr', 'image', 'embed', 'blockquote', 
    'left', 'center', 'right', 'justify'
]

@register_snippet
class Autor(models.Model):
    nombre = models.CharField(max_length=100, verbose_name="Nombre del Autor")
    panels = [FieldPanel('nombre')]
    class Meta:
        db_table = '_home_autor'
        verbose_name = "Autor de la UTRAU"
        verbose_name_plural = "Autores de la UTRAU"
    def __str__(self): return self.nombre

@register_snippet
class Tema(models.Model):
    nombre = models.CharField(max_length=100, verbose_name="Nombre del Tema")
    panels = [FieldPanel('nombre')]
    class Meta:
        db_table = '_home_tema'
        verbose_name = "Tema / Categoría"
        verbose_name_plural = "Temas / Categorías"
    def __str__(self): return self.nombre

@register_snippet
class Suscriptor(models.Model):
    nombre = models.CharField(max_length=150, db_column='nombre', verbose_name="Nombre Completo")
    f_nacimiento = models.DateField(null=True, blank=True, db_column='f_nacimiento', verbose_name="Fecha de Nacimiento")
    departamento = models.CharField(max_length=100, blank=True, db_column='departamento', verbose_name="Departamento")
    email = models.EmailField(blank=True, null=True, db_column='email', verbose_name="Correo Electrónico")
    celular = models.CharField(max_length=30, blank=True, null=True, db_column='celular', verbose_name="Número de WhatsApp")
    recibir_mail = models.BooleanField(default=False, db_column='recibir_mail', verbose_name="Recibir por Mail")
    recibir_whatsapp = models.BooleanField(default=True, db_column='recibir_whatsapp', verbose_name="Recibir por WhatsApp")
    fecha_suscripcion = models.DateTimeField(db_column='fecha_suscripcion', verbose_name="Fecha de Alta")
    activo = models.BooleanField(default=True, db_column='activo', verbose_name="Suscripción Activa")
    
    panels = [FieldPanel('nombre'), FieldPanel('f_nacimiento'), FieldPanel('departamento'), FieldPanel('email'), FieldPanel('celular'), FieldPanel('recibir_mail'), FieldPanel('recibir_whatsapp'), FieldPanel('activo')]
    
    class Meta:
        managed = False 
        db_table = '_home_suscriptor'
        verbose_name = "Suscriptor del Pie"
        verbose_name_plural = "Suscriptores del Pie"
        
    def __str__(self): return self.nombre

class WelcomeBannerBlock(StructBlock):
    banner_text = RichTextBlock(features=EDITOR_COMPLETO, label="Texto de Bienvenida")
    lsu_video_url = URLBlock(required=False, label="Video YouTube")
    class Meta:
        template = "blocks/welcome_banner_block.html"

class UltimaNoticiaBlock(StructBlock):
    titulo_seccion = CharBlock(default="Última Noticia Sindical", required=False, label="Título de la Sección")
    def get_context(self, value, parent_context=None):
        context = super().get_context(value, parent_context=parent_context)
        context['ultima_noticia'] = NoticiaPage.objects.live().filter(
            fecha_publicacion__lte=timezone.now()
        ).order_by('-fecha_publicacion').first()
        return context
    class Meta:
        template = "blocks/ultima_noticia_block.html"
        icon = "radio-full"
        label = "Módulo Última Noticia"

class HomePage(Page):
    body = StreamField([
        ('welcome_banner', WelcomeBannerBlock()),
        ('ultima_noticia', UltimaNoticiaBlock()), 
    ], use_json_field=True, blank=True)
    content_panels = Page.content_panels + [FieldPanel('body')]

    subpage_types = [
        'home.CarpetaNoticiasPage',
        'home.NoticiasIndexPage',
        'home.NoticiaPage',
        'home.StandardPage',
        'home.DocumentGalleryPage',
    ]
    
    class Meta:
        verbose_name = "Página de Inicio (Home)"

    def get_context(self, request):
        context = super().get_context(request)
        idioma_actual = Locale.get_active()
        
        ultimas_noticias = NoticiaPage.objects.live().filter(
            locale=idioma_actual,
            fecha_publicacion__lte=timezone.now()
        ).order_by('-fecha_publicacion')[:5]
        
        context['noticia_principal'] = ultimas_noticias.first() if ultimas_noticias else None
        context['noticias_secundarias'] = ultimas_noticias[1:5] if ultimas_noticias.count() > 1 else []
        return context
    
class CarpetaNoticiasPage(Page):
    subpage_types = ['home.NoticiaPage']
    class Meta:
        verbose_name = "Archivo de Documentos"

class NoticiasIndexPage(Page):
    introduction = RichTextField(blank=True, features=EDITOR_COMPLETO)
    content_panels = Page.content_panels + [FieldPanel('introduction')]
    subpage_types = []
    class Meta:
        verbose_name = "Sección de Noticias Públicas"

    def get_context(self, request):
        context = super().get_context(request)
        idioma_actual = Locale.get_active()
        noticias = NoticiaPage.objects.live().filter(
            locale=idioma_actual,
            fecha_publicacion__lte=timezone.now()
        ).order_by('-fecha_publicacion')
        
        tema_id = request.GET.get('tema')
        autor_id = request.GET.get('autor')
        mes_anio = request.GET.get('mes_anio')
        
        if tema_id:
            noticias = noticias.filter(tema_id=tema_id)
        if autor_id:
            noticias = noticias.filter(autores__id=autor_id)
        if mes_anio:
            try:
                year, month = mes_anio.split('-')
                noticias = noticias.filter(fecha_publicacion__year=year, fecha_publicacion__month=month)
            except ValueError:
                pass

        paginator = Paginator(noticias, 10) 
        page_number = request.GET.get('page')
        try:
            noticias_paginadas = paginator.page(page_number)
        except PageNotAnInteger:
            noticias_paginadas = paginator.page(1)
        except EmptyPage:
            noticias_paginadas = paginator.page(paginator.num_pages)
            
        context['noticias'] = noticias_paginadas
        
        from home.models import Tema, Autor
        context['lista_temas'] = Tema.objects.all()
        context['lista_autores'] = Autor.objects.all()
        
        return context

class NoticiaPage(Page):
    fecha_publicacion = models.DateTimeField(default=timezone.now, verbose_name="Fecha y Hora de Publicación")
    generar_audio = models.BooleanField(default=False, verbose_name="¿Activar reproductor de audio?")
    autores = ParentalManyToManyField('home.Autor', blank=False, related_name='noticias', verbose_name="Autores")
    tema = models.ForeignKey('home.Tema', null=True, blank=False, on_delete=models.SET_NULL, related_name='noticias', verbose_name="Tema")
    main_image = models.ForeignKey('wagtailimages.Image', null=True, blank=False, on_delete=models.SET_NULL, related_name='+')
    copete = models.TextField(blank=False, verbose_name="Copete / Resumen breve")
    body = RichTextField(blank=False, features=EDITOR_COMPLETO, verbose_name="Cuerpo del Artículo")
    
    content_panels = Page.content_panels + [
        MultiFieldPanel([FieldPanel('fecha_publicacion'), FieldPanel('generar_audio')], heading="Control de Difusión"),
        FieldPanel('autores'), FieldPanel('tema'), FieldPanel('main_image'), FieldPanel('copete'), FieldPanel('body'),
        InlinePanel('imagenes_pie', label="Carrusel del Pie")
    ]
    
    class Meta:
        verbose_name = "Artículo de Noticia"

class NoticiaPieImagen(Orderable):
    page = ParentalKey('home.NoticiaPage', on_delete=models.CASCADE, related_name='imagenes_pie')
    image = models.ForeignKey('wagtailimages.Image', on_delete=models.CASCADE, related_name='+')
    panels = [FieldPanel('image')]

class StandardPage(Page):
    body = RichTextField(blank=True, features=EDITOR_COMPLETO)
    content_panels = Page.content_panels + [FieldPanel('body')]
    class Meta:
        verbose_name = "Página de Contenido (Estándar)"

class DocumentGalleryPage(Page):
    introduction = RichTextField(blank=True, features=EDITOR_COMPLETO)
    content_panels = Page.content_panels + [FieldPanel('introduction'), InlinePanel('document_items', label="Documentos")]
    class Meta:
        verbose_name = "Galería de Documentos"

class DocumentGalleryItem(Orderable):
    page = ParentalKey('home.DocumentGalleryPage', on_delete=models.CASCADE, related_name='document_items')
    title = models.CharField(max_length=255)
    document = models.ForeignKey('wagtaildocs.Document', on_delete=models.CASCADE, related_name='+')
    panels = [FieldPanel('title'), FieldPanel('document')]

class Comentario(models.Model):
    noticia = models.ForeignKey('home.NoticiaPage', on_delete=models.CASCADE, related_name='comentarios')
    usuario = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='comentarios_realizados')
    padre = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, related_name='respuestas')
    texto = models.TextField()
    fecha_creacion = models.DateTimeField(auto_now_add=True)
    activo = models.BooleanField(default=True)
    class Meta:
        db_table = '_comentarios_noticias' 

class ValoracionComentario(models.Model):
    comentario = models.ForeignKey(Comentario, on_delete=models.CASCADE, related_name='valoraciones')
    usuario = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='valoraciones_comentarios')
    valor = models.SmallIntegerField() 
    fecha_voto = models.DateTimeField(auto_now_add=True)
    class Meta:
        db_table = '_valoraciones_comentarios'
        unique_together = ('comentario', 'usuario')

class ValoracionNoticia(models.Model):
    noticia = models.ForeignKey('home.NoticiaPage', on_delete=models.CASCADE, related_name='valoraciones_noticia')
    usuario = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='valoraciones_noticias')
    puntuacion = models.IntegerField()
    fecha_voto = models.DateTimeField(auto_now_add=True)
    class Meta:
        db_table = '_valoraciones_noticias'
        unique_together = ('noticia', 'usuario')

@receiver(post_save, sender=NoticiaPage)
def espejo_noticia_save(sender, instance, **kwargs):
    if kwargs.get('raw'): return
    if not instance.live: return
    
    if 'mysql' in connection.vendor:
        with connection.cursor() as cursor:
            cursor.execute("""
                INSERT INTO `espejo_noticias_limpias` (id, titulo, copete, fecha_publicacion, url)
                VALUES (%s, %s, %s, %s, %s)
                ON DUPLICATE KEY UPDATE
                titulo=VALUES(titulo), copete=VALUES(copete), fecha_publicacion=VALUES(fecha_publicacion), url=VALUES(url);
            """, [instance.id, instance.title, instance.copete, instance.fecha_publicacion, instance.url])

@receiver(post_delete, sender=NoticiaPage)
def espejo_noticia_delete(sender, instance, **kwargs):
    try:
        if 'mysql' in connection.vendor:
            with connection.cursor() as cursor:
                cursor.execute("DELETE FROM `espejo_noticias_limpias` WHERE id = %s", [instance.id])
    except Exception:
        pass