from datetime import timedelta

from django.db import transaction
from django.db.models import Count
from django.db.models import F
from django.db.models import Q
from django.utils import timezone
from rest_framework.viewsets import ModelViewSet
from usuarios.permissions import IsEscritor
from .models import Categoria, LikeArtigo, LikeComentario, Artigo, ArtigoVisualizacao, Comentario, Tag
from .serializers import ArtigoSerializer, CategoriaSerializer, ComentarioSerializer, TagSerializer
from notificacoes.models import Notificacao
from rest_framework.response import Response
from rest_framework.decorators import action
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter
from rest_framework.permissions import AllowAny, IsAuthenticated

class ArtigoViewSet(ModelViewSet):
    permission_classes = [AllowAny]
    queryset = Artigo.objects.all()
    serializer_class = ArtigoSerializer

    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_fields = {
        'autor__email': ['exact'],
        'titulo': ['exact', 'icontains'],
        'conteudo': ['icontains'],
        'is_artigo_picante': ['exact'],
        'categoria': ['exact'],
    }
    ordering_fields = ['visualizacoes', 'data_criacao']

    def perform_create(self, serializer):
        serializer.save(autor=self.request.user)

    def get_permissions(self):
        if self.action in {"list", "retrieve", "comentarios", "visualizacao"}:
            return [AllowAny()]
        if self.action == "like":
            return [IsAuthenticated()]
        if self.action in {"create", "update", "partial_update", "destroy"}:
            return [IsAuthenticated(), IsEscritor()]
        return [IsAuthenticated()]

    @action(detail=True, methods=['post'])
    def visualizacao(self, request, *args, **kwargs):
        artigo = self.get_object()
        now = timezone.now()
        window = timedelta(minutes=30)
        counted = False

        if request.user and request.user.is_authenticated:
            with transaction.atomic():
                visualizacao, created = ArtigoVisualizacao.objects.select_for_update().get_or_create(
                    usuario=request.user,
                    artigo=artigo,
                    defaults={"ultima_visualizacao": now},
                )
                deve_contar = created or (now - visualizacao.ultima_visualizacao) >= window
                if deve_contar:
                    Artigo.objects.filter(pk=artigo.pk).update(visualizacoes=F("visualizacoes") + 1)
                    ArtigoVisualizacao.objects.filter(pk=visualizacao.pk).update(ultima_visualizacao=now)
                    counted = True
        else:
            Artigo.objects.filter(pk=artigo.pk).update(visualizacoes=F("visualizacoes") + 1)
            counted = True

        artigo.refresh_from_db(fields=["visualizacoes"])
        return Response({"counted": counted, "visualizacoes": artigo.visualizacoes})

    @action(detail=True, methods=['post', 'delete'])
    def like(self, request, *args, **kwargs):
        artigo = self.get_object()
        like_qs = LikeArtigo.objects.filter(usuario=request.user, artigo=artigo)

        if request.method.lower() == "delete":
            deleted, _ = like_qs.delete()
            return Response(
                {
                    "mensagem": "Like removido." if deleted else "Você ainda não tinha dado like.",
                    "liked": False,
                    "total_likes": LikeArtigo.objects.filter(artigo=artigo).count(),
                }
            )

        if like_qs.exists():
            like_qs.delete()
            liked = False
            mensagem = "Like removido."
        else:
            LikeArtigo.objects.create(usuario=request.user, artigo=artigo)
            liked = True
            mensagem = "Gostou do artigo."

        return Response(
            {
                "mensagem": mensagem,
                "liked": liked,
                "total_likes": LikeArtigo.objects.filter(artigo=artigo).count(),
            }
        )

    @action(detail=True, methods=['get'])
    def comentarios(self, request, pk=None):
        artigo = self.get_object()
        comentarios = artigo.comentarios.all()
        serializer = ComentarioSerializer(comentarios, many=True, context=self.get_serializer_context())
        return Response(serializer.data)

    def get_queryset(self):
        queryset = Artigo.objects.annotate(
            total_likes=Count('likeartigo')
        )

        search = self.request.query_params.get("q", "").strip()
        categoria = self.request.query_params.get("categoria", "").strip()

        if search:
            queryset = queryset.filter(
                Q(titulo__icontains=search)
                | Q(conteudo__icontains=search)
                | Q(categoria__nome__icontains=search)
                | Q(tags__nome__icontains=search)
                | Q(autor__first_name__icontains=search)
                | Q(autor__last_name__icontains=search)
                | Q(autor__email__icontains=search)
            )

        if categoria:
            queryset = queryset.filter(categoria_id=categoria)

        return queryset.distinct().order_by('-total_likes', '-visualizacoes')

class ComentarioViewSet(ModelViewSet):
    permission_classes = [IsAuthenticated]

    queryset = Comentario.objects.all().order_by('-data_criacao')
    serializer_class = ComentarioSerializer

    def perform_create(self, serializer):
        comentario = serializer.save(autor=self.request.user)

        if comentario.resposta:
            Notificacao.objects.create(
                usuario=comentario.resposta.autor,
                mensagem=f'Novo comentário em seu comentário: {comentario.texto[:50] + "..."}'
            )

    @action(detail=True, methods=['post', 'delete'])
    def like(self, request, *args, **kwargs):
        comentario = self.get_object()
        like_qs = LikeComentario.objects.filter(usuario=request.user, comentario=comentario)

        if request.method.lower() == "delete":
            deleted, _ = like_qs.delete()
            return Response(
                {
                    "mensagem": "Like removido." if deleted else "Você ainda não tinha dado like.",
                    "liked": False,
                    "total_likes": LikeComentario.objects.filter(comentario=comentario).count(),
                }
            )

        if like_qs.exists():
            like_qs.delete()
            liked = False
            mensagem = "Like removido."
        else:
            LikeComentario.objects.create(usuario=request.user, comentario=comentario)
            liked = True
            mensagem = "Gostou do comentário."

        return Response(
            {
                "mensagem": mensagem,
                "liked": liked,
                "total_likes": LikeComentario.objects.filter(comentario=comentario).count(),
            }
        )

class CategoriaViewSet(ModelViewSet):
    permission_classes = [AllowAny]

    queryset = Categoria.objects.all().order_by("nome", "id")
    serializer_class = CategoriaSerializer

    def get_permissions(self):
        if self.action in {"list", "retrieve"}:
            return [AllowAny()]
        return [IsAuthenticated()]

class TagViewSet(ModelViewSet):
    permission_classes = [AllowAny]

    queryset = Tag.objects.all()
    serializer_class = TagSerializer

    def get_permissions(self):
        if self.action in {"list", "retrieve"}:
            return [AllowAny()]
        return [IsAuthenticated()]
