from rest_framework import status
from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate

from notificacoes.models import Notificacao
from usuarios.models import Usuario

from .models import Artigo, Comentario, LikeArtigo, LikeComentario
from .views import ArtigoViewSet, ComentarioViewSet


class ArtigosModuleTests(APITestCase):
    def setUp(self):
        self.factory = APIRequestFactory()
        self.escritor = Usuario.objects.create_user(
            email="escritor@example.com",
            password="Senha@12345",
            first_name="Escritor",
            last_name="Teste",
            is_escritor=True,
        )
        self.leitor = Usuario.objects.create_user(
            email="leitor@example.com",
            password="Senha@12345",
            first_name="Leitor",
            last_name="Teste",
            is_escritor=False,
        )
        self.artigo = Artigo.objects.create(autor=self.escritor, titulo="Artigo 1", conteudo="Conteúdo")

    def test_escritor_consegue_criar_artigo(self):
        view = ArtigoViewSet.as_view({"post": "create"})
        request = self.factory.post(
            "/api/artigos/",
            {"titulo": "Novo artigo", "conteudo": "Texto"},
            format="json",
        )
        force_authenticate(request, user=self.escritor)
        response = view(request)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        artigo_id = response.data["id"]
        artigo = Artigo.objects.get(id=artigo_id)
        self.assertEqual(artigo.autor_id, self.escritor.id)

    def test_nao_escritor_nao_consegue_criar_artigo(self):
        view = ArtigoViewSet.as_view({"post": "create"})
        request = self.factory.post(
            "/api/artigos/",
            {"titulo": "Novo artigo", "conteudo": "Texto"},
            format="json",
        )
        force_authenticate(request, user=self.leitor)
        response = view(request)
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

    def test_retrieve_incrementa_visualizacoes(self):
        view = ArtigoViewSet.as_view({"get": "retrieve"})
        request = self.factory.get(f"/api/artigos/{self.artigo.id}/")
        force_authenticate(request, user=self.leitor)
        response = view(request, pk=self.artigo.id)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.artigo.refresh_from_db()
        self.assertEqual(self.artigo.visualizacoes, 1)

    def test_retrieve_visualizacao_controlada(self):
        view = ArtigoViewSet.as_view({"get": "retrieve"})

        request1 = self.factory.get(f"/api/artigos/{self.artigo.id}/")
        force_authenticate(request1, user=self.leitor)
        response1 = view(request1, pk=self.artigo.id)
        self.assertEqual(response1.status_code, status.HTTP_200_OK)

        request2 = self.factory.get(f"/api/artigos/{self.artigo.id}/")
        force_authenticate(request2, user=self.leitor)
        response2 = view(request2, pk=self.artigo.id)
        self.assertEqual(response2.status_code, status.HTTP_200_OK)

        self.artigo.refresh_from_db()
        self.assertEqual(self.artigo.visualizacoes, 1)

    def test_like_artigo_toggle(self):
        view = ArtigoViewSet.as_view({"post": "like"})
        request1 = self.factory.post(f"/api/artigos/{self.artigo.id}/like/")
        force_authenticate(request1, user=self.leitor)
        response1 = view(request1, pk=self.artigo.id)
        self.assertEqual(response1.status_code, status.HTTP_200_OK)
        self.assertEqual(LikeArtigo.objects.filter(usuario=self.leitor, artigo=self.artigo).count(), 1)

        request2 = self.factory.post(f"/api/artigos/{self.artigo.id}/like/")
        force_authenticate(request2, user=self.leitor)
        response2 = view(request2, pk=self.artigo.id)
        self.assertEqual(response2.status_code, status.HTTP_200_OK)

        self.assertEqual(LikeArtigo.objects.filter(usuario=self.leitor, artigo=self.artigo).count(), 0)

    def test_criar_comentario_e_resposta_cria_notificacao(self):
        create_view = ComentarioViewSet.as_view({"post": "create"})

        request1 = self.factory.post(
            "/api/comentarios/",
            {"artigo": self.artigo.id, "texto": "Comentário 1"},
            format="json",
        )
        force_authenticate(request1, user=self.leitor)
        response1 = create_view(request1)
        self.assertEqual(response1.status_code, status.HTTP_201_CREATED)
        comentario_id = response1.data["id"]

        request2 = self.factory.post(
            "/api/comentarios/",
            {"artigo": self.artigo.id, "texto": "Resposta", "resposta": comentario_id},
            format="json",
        )
        force_authenticate(request2, user=self.escritor)
        response2 = create_view(request2)
        self.assertEqual(response2.status_code, status.HTTP_201_CREATED)

        self.assertTrue(Notificacao.objects.filter(usuario=self.leitor).exists())

    def test_like_comentario_toggle(self):
        comentario = Comentario.objects.create(autor=self.leitor, artigo=self.artigo, texto="Comentário")
        view = ComentarioViewSet.as_view({"post": "like"})

        request1 = self.factory.post(f"/api/comentarios/{comentario.id}/like/")
        force_authenticate(request1, user=self.escritor)
        response1 = view(request1, pk=comentario.id)
        self.assertEqual(response1.status_code, status.HTTP_200_OK)
        self.assertEqual(LikeComentario.objects.filter(usuario=self.escritor, comentario=comentario).count(), 1)

        request2 = self.factory.post(f"/api/comentarios/{comentario.id}/like/")
        force_authenticate(request2, user=self.escritor)
        response2 = view(request2, pk=comentario.id)
        self.assertEqual(response2.status_code, status.HTTP_200_OK)

        self.assertEqual(LikeComentario.objects.filter(usuario=self.escritor, comentario=comentario).count(), 0)
