import pytest
from django.contrib.auth import get_user_model
from model_bakery import baker
from contact_us.models import ContactUs
from unittest.mock import patch
import uuid

Users = get_user_model()


@pytest.mark.django_db()
class TestContactUsModel:
    def test_return_str_model(self):
        contact_us = baker.make(ContactUs)
        assert (
            str(contact_us)
            == f"{contact_us.email} - submitted on {contact_us.created_at.strftime('%B %d, %Y')}"
        )


# Create your tests here.
@pytest.mark.django_db()
class TestContactUsFetch:
    def setup_method(self):
        self.admin = baker.make(Users, is_staff=True)
        self.user = baker.make(Users, is_staff=False)

        self.contact_us_1 = baker.make(ContactUs)
        self.contact_us_2 = baker.make(ContactUs)

    def test_fetch_contact_us_by_any_user_return_403(self, authenticate_user):
        api_client = authenticate_user()
        response = api_client.get("/api/contact-us/")

        assert response.status_code == 403

    def test_fetch_contact_us_by_admin_return200(self, authenticate_user):
        api_client = authenticate_user(user=self.admin)
        response = api_client.get("/api/contact-us/")

        assert response.status_code == 200
        assert response.data["count"] == 2


@pytest.mark.django_db()
class TestContactUsCreate:
    def setup_method(self):
        self.user = baker.make(Users, is_staff=False)

    @patch("contact_us.views.send_contact_us_inquiry_emails.delay")
    def test_create_inquiry_by_user_return_201(
        self, mock_send_emails, authenticate_user
    ):
        api_client = authenticate_user(user=self.user)

        data = {
            "first_name": "John",
            "last_name": "Doe",
            "email": "johndoe@example.com",
            "contact_number": "09123456789",
            "inquiry": "I need help with my website",
        }

        response = api_client.post("/api/contact-us/", data=data)

        assert response.status_code == 200
        assert response.data["message"] == "Inquiry has been submitted successfully."
        mock_send_emails.assert_called_once()


@pytest.mark.django_db()
class TestContactUsDelete:
    def setup_method(self):
        self.admin = baker.make(Users, is_staff=True)
        self.user = baker.make(Users, is_staff=False)

        self.contact_us_1 = baker.make(ContactUs)

    def test_delete_inquiry_by_non_admin_return_403(self, authenticate_user):
        api_client = authenticate_user(user=self.user)

        response = api_client.delete(f"/api/contact-us/{self.contact_us_1.id}/")

        assert response.status_code == 403

    def test_delete_inquiry_by_admin_return_204(self, authenticate_user):
        api_client = authenticate_user(user=self.admin)

        response = api_client.delete(f"/api/contact-us/{self.contact_us_1.id}/")

        assert response.status_code == 204


@pytest.mark.django_db()
class TestContactUsMarkStatus:
    def setup_method(self):
        self.admin = baker.make(Users, is_staff=True)
        self.user = baker.make(Users, is_staff=False)

        self.contact_us_1 = baker.make(ContactUs)

    def test_mark_status_inquiry_by_non_admin_return_403(self, authenticate_user):
        api_client = authenticate_user(user=self.user)

        data = {"id": str(self.contact_us_1.id), "status": "endorsed"}

        response = api_client.post(f"/api/contact-us/mark-status/", data=data)

        assert response.status_code == 403

    def test_mark_status_inquiry_by_admin_return_204(self, authenticate_user):
        api_client = authenticate_user(user=self.admin)

        data = {"inquiry_id": str(self.contact_us_1.id), "status": "endorsed"}

        response = api_client.post(f"/api/contact-us/mark-status/", data=data)

        assert response.status_code == 200
        assert response.data["message"] == "Inquiry status was updated successfully."

    def test_mark_status_invalid_inquiry_by_admin_return_404(self, authenticate_user):
        api_client = authenticate_user(user=self.admin)

        random_uuid = uuid.uuid4()
        data = {"inquiry_id": str(random_uuid), "status": "endorsed"}

        response = api_client.post(f"/api/contact-us/mark-status/", data=data)

        assert response.status_code == 404
        assert response.data["message"] == "Inquiry not found."
