"""
Tests for pages views.
"""

from django.test import RequestFactory
from django.urls import reverse
from django.contrib.auth.models import AnonymousUser

from django_mock_queries.query import MockSet
from django_mock_queries.query import MockModel

from pages.views import IndexView
from pages.views import ContactView
from pages.views import ChangeLanguageView
from users.forms import NewUserForm
from users.models import User


def test_change_language_view_default_redirect():
    request = RequestFactory().get(
        reverse("pages:change-language", kwargs={"language": "en"}),
    )

    view = ChangeLanguageView()
    view.setup(request)
    url = view.get_redirect_url()

    assert url == reverse("pages:index")


def test_change_language_view_referer_redirect():
    request = RequestFactory().get(
        reverse("pages:change-language", kwargs={"language": "en"}),
        HTTP_REFERER="/referer",
    )

    view = ChangeLanguageView()
    view.setup(request)
    url = view.get_redirect_url()

    assert url == "/referer"


def test_change_language_view_actives_translations(mocker):
    request = RequestFactory().get(
        reverse("pages:change-language", kwargs={"language": "en"}),
    )
    request.session = {}
    translation_mock = mocker.patch("pages.views.translation.activate")

    view = ChangeLanguageView()
    view.setup(request)
    view.get(request, language="en")

    translation_mock.assert_called_once_with("en")


def test_change_language_view_set_session_language(mocker):
    request = RequestFactory().get(
        reverse("pages:change-language", kwargs={"language": "en"}),
    )
    request.session = {}
    mocker.patch("pages.views.translation.activate")

    view = ChangeLanguageView()
    view.setup(request)
    view.get(request, language="en")

    assert request.session == {"_language": "en"}


def test_index_visitor_template_name():
    request = RequestFactory().get(reverse("pages:index"))
    request.user = AnonymousUser()

    view = IndexView()
    view.setup(request)
    templates = view.get_template_names()

    assert templates == ["pages/landing.html"]


def test_index_user_template_name():
    request = RequestFactory().get(reverse("pages:index"))
    request.user = User()

    view = IndexView()
    view.setup(request)
    templates = view.get_template_names()

    assert templates == ["pages/home.html"]


def test_index_view_for_visitors():
    """
    Test index page response for visitors.
    """
    request = RequestFactory().get(reverse("pages:index"))
    request.user = AnonymousUser()

    view = IndexView()
    view.setup(request)
    response = view.get(request)

    assert response.status_code == 200


def test_index_view_for_users(mocker):
    """
    Test index page response for users.
    """
    cards_mock = mocker.patch("pages.views.Card.objects.filter")
    cards_mock.return_value = MockSet()
    news_mock = mocker.patch("pages.views.get_latest_news", MockSet())
    news_mock.return_value = MockSet()
    request = RequestFactory().get(reverse("pages:index"))
    user = User(username="test", email="test@example.com")
    request.user = user

    view = IndexView()
    view.setup(request)
    response = view.get(request)

    assert response.status_code == 200


def test_index_visitor_contains_register_form():
    request = RequestFactory().get(reverse("pages:index"))
    request.user = AnonymousUser()

    view = IndexView()
    view.setup(request)
    context = view.get_context_data()

    assert isinstance(context["register_form"], NewUserForm)


def test_index_get_user_default_card(mocker):
    user = User(username="test", email="test@example.com")
    default_card = MockModel(
        mock_name="first default",
        user=user,
        default=True,
    )
    cards_qs = MockSet(
        MockModel(mock_name="non default", user=user, default=False),
        default_card,
        MockModel(mock_name="second default", user=user, default=True),
    )
    mocker.patch("pages.views.Card.objects", cards_qs)
    request = RequestFactory().get(reverse("pages:index"))
    request.user = user

    view = IndexView()
    view.setup(request)
    card = view.get_user_default_card()

    assert card == default_card


def test_index_user_context_contains_default_card(mocker):
    user = User(username="test", email="test@example.com")
    default_card = MockModel(
        mock_name="first default",
        user=user,
        default=True,
    )
    news_mock = mocker.patch("pages.views.get_latest_news")
    news_mock.return_value = MockSet()
    request = RequestFactory().get(reverse("pages:index"))
    request.user = user

    view = IndexView()
    view.setup(request)
    default_card_mock = mocker.patch.object(view, "get_user_default_card")
    default_card_mock.return_value = default_card
    context = view.get_context_data()

    assert context["card"] == default_card


def test_index_user_contains_news(mocker):
    user = User(username="test", email="test@example.com")
    cards_mock = mocker.patch("pages.views.Card.objects")
    cards_mock.return_value = MockSet()
    news_qs = MockSet()
    latest_news_mock = mocker.patch("pages.views.get_latest_news")
    latest_news_mock.return_value = news_qs
    request = RequestFactory().get(reverse("pages:index"))
    request.user = user

    view = IndexView()
    view.setup(request)
    context = view.get_context_data()

    assert context["news"] == news_qs


def test_contact_view_send_mail(mocker):
    mail_mock = mocker.patch("pages.views.send_mail")
    mocker.patch("django.contrib.messages.success")
    form = mocker.Mock()
    form.cleaned_data = {"comentario": "message", "correo": "test@mail.com"}
    request = RequestFactory().get(reverse("pages:contact"))

    view = ContactView()
    view.setup(request)
    view.form_valid(form)

    mail_mock.assert_called_once_with(
        "Contacto EcCard",
        "message",
        "test@mail.com",
        ["info@eccard.com.mx"],
        fail_silently=False,
    )


def test_contact_displays_success_message(mocker):
    mocker.patch("pages.views.send_mail")
    message_mock = mocker.patch("django.contrib.messages.success")
    form = mocker.Mock()
    form.cleaned_data = {"comentario": "test", "correo": "test"}
    request = RequestFactory().get(reverse("pages:contact"))

    view = ContactView()
    view.setup(request)
    view.form_valid(form)

    message_mock.assert_called_once_with(request, "Message sent successfully")
