import pytest
from django.contrib.auth import get_user_model
from model_bakery import baker
from PIL import Image
from io import BytesIO
from unittest.mock import patch
from django.core.files.uploadedfile import SimpleUploadedFile

Users = get_user_model()


# Create your tests here.
@pytest.mark.django_db()
class TestHeroBannersUpload:
    def setup_method(self):
        self.copywriter = baker.make(Users, is_staff=True, role="Copywriter")
        self.web_admin = baker.make(Users, is_staff=True, role="Web Admin")

        self.user = baker.make(Users, is_staff=False)

    def test_upload_hero_banner_by_non_admin_returns_403(self, authenticate_user):
        api_client = authenticate_user()

        mock_image = SimpleUploadedFile(
            "image.jpg", b"mock-image-content", content_type="image/jpeg"
        )

        data = {"image": mock_image}

        response = api_client.post("/api/hero-banners/upload/", data=data)

        assert response.status_code == 403

    def test_upload_hero_banner_by_non_web_admin_returns_403(self, authenticate_user):
        api_client = authenticate_user(user=self.copywriter)

        mock_image = SimpleUploadedFile(
            "image.jpg", b"mock-image-content", content_type="image/jpeg"
        )

        data = {"image": mock_image}

        response = api_client.post("/api/hero-banners/upload/", data=data)

        assert response.status_code == 403

    @patch("hero_banners.views.R2")
    def test_upload_hero_banner_by_web_admin_and_catched_exception_returns_500(
        self, mock_r2, authenticate_user
    ):
        api_client = authenticate_user(user=self.web_admin)

        mock_r2_instance = mock_r2.return_value
        mock_r2_instance.upload_fileobj.side_effect = Exception("Mocked upload error")

        # Mock Image
        image = Image.new("RGB", (100, 100), color=(255, 0, 0))
        image_io = BytesIO()
        image.save(image_io, format="JPEG")
        image_io.seek(0)

        mock_image = SimpleUploadedFile(
            "image.jpg", image_io.getvalue(), content_type="image/jpeg"
        )

        data = {"image": mock_image}

        response = api_client.post("/api/hero-banners/upload/", data=data)

        assert response.status_code == 500
        assert response.data["message"] == "Error occurred while uploading."

    @patch("hero_banners.views.R2")
    def test_upload_hero_banner_by_web_admin_returns_200(
        self, mock_r2, authenticate_user
    ):
        api_client = authenticate_user(user=self.web_admin)

        mock_r2_instance = mock_r2.return_value
        mock_r2_instance.upload_fileobj.return_value = "/hero_banners/image.jpg"

        # Mock Image
        image = Image.new("RGB", (100, 100), color=(255, 0, 0))
        image_io = BytesIO()
        image.save(image_io, format="JPEG")
        image_io.seek(0)

        mock_image = SimpleUploadedFile(
            "image.jpg", image_io.getvalue(), content_type="image/jpeg"
        )

        data = {"image": mock_image}

        response = api_client.post("/api/hero-banners/upload/", data=data)

        assert response.status_code == 200
        assert (
            response.data["message"]
            == f"Image {str(mock_image)} uploaded successfully."
        )
        assert response.data["image_url"] == "/hero_banners/image.jpg"
