from django.test import TestCase
from django.contrib.auth import get_user_model
from rest_framework.test import APIClient
from rest_framework import status
from django.urls import reverse
from likes.models import LikeComment

User = get_user_model()


class CommentTestCase(TestCase):
    def setUp(self):
        self.client = APIClient()
        self.user = User.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )
        self.user2 = User.objects.create_user(
            username='user2',
            email='user2@example.com',
            password='user2pass123'
        )
        from posts.models import Post
        self.post = Post.objects.create(
            content='Test post',
            created_by=self.user
        )
        self.comment_data = {
            'post': self.post.id,
            'content': 'This is a test comment'
        }

    def test_create_comment(self):
        """Test creating a comment"""
        self.client.force_authenticate(user=self.user2)
        response = self.client.post(reverse('create_comment'), self.comment_data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['content'], 'This is a test comment')

    def test_create_comment_unauthenticated(self):
        """Test creating a comment without authentication"""
        response = self.client.post(reverse('create_comment'), self.comment_data)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_list_comments(self):
        """Test listing comments for a post"""
        from comments.models import Comment
        Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        self.client.force_authenticate(user=self.user)
        response = self.client.get(reverse('list_comments', args=[self.post.id]))
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_update_comment(self):
        """Test updating a comment"""
        from comments.models import Comment
        comment = Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        self.client.force_authenticate(user=self.user2)
        update_data = {'content': 'Updated comment'}
        response = self.client.put(reverse('update_comment', args=[comment.id]), update_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['content'], 'Updated comment')

    def test_update_comment_unauthorized(self):
        """Test updating a comment by non-creator"""
        from comments.models import Comment
        comment = Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        self.client.force_authenticate(user=self.user)
        update_data = {'content': 'Updated comment'}
        response = self.client.put(reverse('update_comment', args=[comment.id]), update_data)
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

    def test_delete_comment(self):
        """Test deleting a comment (soft delete)"""
        from comments.models import Comment
        comment = Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        self.client.force_authenticate(user=self.user2)
        response = self.client.delete(reverse('delete_comment', args=[comment.id]))
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        comment.refresh_from_db()
        self.assertFalse(comment.is_active)

    def test_delete_comment_unauthorized(self):
        """Test deleting a comment by non-creator"""
        from comments.models import Comment
        comment = Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        self.client.force_authenticate(user=self.user)
        response = self.client.delete(reverse('delete_comment', args=[comment.id]))
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

    def test_like_comment(self):
        """Test liking a comment"""
        from comments.models import Comment
        comment = Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        self.client.force_authenticate(user=self.user)
        response = self.client.post(reverse('like_comment', args=[comment.id]))
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertTrue(LikeComment.objects.filter(user=self.user, comment=comment).exists())

    def test_like_comment_already_liked(self):
        """Test liking a comment already liked"""
        from comments.models import Comment
        comment = Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        LikeComment.objects.create(user=self.user, comment=comment)
        self.client.force_authenticate(user=self.user)
        response = self.client.post(reverse('like_comment', args=[comment.id]))
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_unlike_comment(self):
        """Test unliking a comment"""
        from comments.models import Comment
        comment = Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        LikeComment.objects.create(user=self.user, comment=comment)
        self.client.force_authenticate(user=self.user)
        response = self.client.delete(reverse('unlike_comment', args=[comment.id]))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertFalse(LikeComment.objects.filter(user=self.user, comment=comment).exists())

    def test_unlike_comment_not_liked(self):
        """Test unliking a comment not liked"""
        from comments.models import Comment
        comment = Comment.objects.create(
            post=self.post,
            created_by=self.user2,
            content='Test comment'
        )
        self.client.force_authenticate(user=self.user)
        response = self.client.delete(reverse('unlike_comment', args=[comment.id]))
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)