from django.test import TestCase
from rest_framework import serializers
from unittest.mock import Mock, MagicMock
from io import BytesIO

from api.property_api.property.serializers.review_serializer import PropertyReviewsSerializer


class PropertyReviewsSerializerValidationTest(TestCase):
    """Test mutual exclusivity validation for image and video uploads"""

    def setUp(self):
        """Set up test fixtures"""
        # Create mock file objects
        self.mock_image = Mock()
        self.mock_image.name = 'test_image.jpg'
        self.mock_image.size = 1024 * 1024  # 1MB
        self.mock_image.content_type = 'image/jpeg'
        self.mock_image.read = Mock(return_value=b'fake image data')
        
        self.mock_video = Mock()
        self.mock_video.name = 'test_video.mp4'
        self.mock_video.size = 10 * 1024 * 1024  # 10MB
        self.mock_video.content_type = 'video/mp4'
        self.mock_video.read = Mock(return_value=b'fake video data')

    def test_validate_both_image_and_video_raises_error(self):
        """Test that providing both image and video raises ValidationError"""
        serializer = PropertyReviewsSerializer()
        
        attrs = {
            'review_image': self.mock_image,
            'review_video': self.mock_video,
            'review_star': 5,
            'message': 'Great property!'
        }
        
        with self.assertRaises(serializers.ValidationError) as context:
            serializer.validate(attrs)
        
        self.assertIn("Cannot upload both image and video", str(context.exception))

    def test_validate_only_image_succeeds(self):
        """Test that providing only image passes validation"""
        serializer = PropertyReviewsSerializer()
        
        attrs = {
            'review_image': self.mock_image,
            'review_star': 5,
            'message': 'Great property!'
        }
        
        # Should not raise any exception
        result = serializer.validate(attrs)
        self.assertEqual(result, attrs)

    def test_validate_only_video_succeeds(self):
        """Test that providing only video passes validation"""
        serializer = PropertyReviewsSerializer()
        
        attrs = {
            'review_video': self.mock_video,
            'review_star': 5,
            'message': 'Great property!'
        }
        
        # Should not raise any exception
        result = serializer.validate(attrs)
        self.assertEqual(result, attrs)

    def test_validate_neither_image_nor_video_succeeds(self):
        """Test that providing neither image nor video passes validation"""
        serializer = PropertyReviewsSerializer()
        
        attrs = {
            'review_star': 5,
            'message': 'Great property!'
        }
        
        # Should not raise any exception
        result = serializer.validate(attrs)
        self.assertEqual(result, attrs)

    def test_validate_with_none_values_succeeds(self):
        """Test that None values for image and video pass validation"""
        serializer = PropertyReviewsSerializer()
        
        attrs = {
            'review_image': None,
            'review_video': None,
            'review_star': 4,
            'message': 'Nice location'
        }
        
        # Should not raise any exception
        result = serializer.validate(attrs)
        self.assertEqual(result, attrs)
