from django.utils import timezone
from django.contrib.auth.models import User
from unittest import skip
from rest_framework import status
from rest_framework.test import APITestCase
from webapp.models import Signup
from webapp.tests.signup_fixture import (
    createSignupForm,
    createSignupObject,
    createSignupRequest,
    ALL_QUESTION_TYPES,
    ALL_QUESTION_TYPES_ANSWER,
    TEXT_SCHEMA,
    RADIO_SCHEMA,
    CBOX_SCHEMA,
)

URL = "/api/signup/"


class SignupErrorTestCase(APITestCase):
    def setUp(self):
        self.signupForm = createSignupForm()
        self.signupFormText = createSignupForm(
            name="Form2", questions=[ALL_QUESTION_TYPES[0]], schema=TEXT_SCHEMA
        )
        self.signupFormRadio = createSignupForm(
            name="Form3", questions=[ALL_QUESTION_TYPES[1]], schema=RADIO_SCHEMA
        )
        self.signupFormCheck = createSignupForm(
            name="Form4", questions=[ALL_QUESTION_TYPES[2]], schema=CBOX_SCHEMA
        )
        self.hiddenForm = createSignupForm(visible=False)
        day_from_now = timezone.now() + timezone.timedelta(days=1)
        day_before_now = timezone.now() + timezone.timedelta(days=-1)
        self.signupFormNotStarted = createSignupForm(
            start_time=day_from_now, end_time=day_from_now
        )
        self.signupFormEnded = createSignupForm(
            start_time=day_before_now, end_time=timezone.now()
        )

        self.signup1 = createSignupObject("1", self.signupForm, ALL_QUESTION_TYPES)
        self.signup2 = createSignupObject("2", self.signupForm, ALL_QUESTION_TYPES)

        username, password = "test_admin", "password123"
        self.authClient = User.objects.create_superuser(
            username, "myemail@test.com", password
        )

    def test_get_all_unauthorized(self):
        response = self.client.get(URL, format="json")
        self.assertTrue(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_get_single_unauthorized(self):
        id = self.signup1.id
        response = self.client.get(f"{URL}{id}/", format="json")
        self.assertTrue(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_create_signup_404(self):
        new = createSignupRequest("asd", 3001, ALL_QUESTION_TYPES_ANSWER)
        response = self.client.post(URL, new, format="json")
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        self.assertEqual(Signup.objects.count(), 2)

    def test_create_signup_not_started(self):
        new = createSignupRequest(
            "asd", self.signupFormNotStarted.id, ALL_QUESTION_TYPES_ANSWER
        )
        response = self.client.post(URL, new, format="json")
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        self.assertEqual(Signup.objects.count(), 2)

    def test_create_signup_ended(self):
        new = createSignupRequest(
            "asd", self.signupFormEnded.id, ALL_QUESTION_TYPES_ANSWER
        )
        response = self.client.post(URL, new, format="json")
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        self.assertEqual(Signup.objects.count(), 2)

    def test_create_empty_body(self):
        response = self.client.post(
            URL, createSignupRequest("", self.signupForm.id, {}), format="json"
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_array_body(self):
        response = self.client.post(
            URL, createSignupRequest("", self.signupForm.id, []), format="json"
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    @skip("We allow extra signup body because of info fields")
    def test_create_extra_body(self):
        testInput = ALL_QUESTION_TYPES_ANSWER.copy()
        testInput["newId"] = "Oon extraa"
        response = self.client.post(
            URL, createSignupRequest("", self.signupForm.id, testInput), format="json"
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_bad_id(self):
        response = self.client.post(
            URL,
            createSignupRequest("", self.signupFormText.id, {"malformed": "Tekstiä"}),
            format="json",
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_bad_type_text(self):
        response = self.client.post(
            URL,
            createSignupRequest("", self.signupFormText.id, {"j5CeRZDvl": 123}),
            format="json",
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_bad_data_checkbox(self):
        response = self.client.post(
            URL,
            createSignupRequest("", self.signupFormCheck.id, {"i10d426d5": ["D"]}),
            format="json",
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_bad_type_checkbox(self):
        response = self.client.post(
            URL,
            createSignupRequest(
                "",
                self.signupFormCheck.id,
                {"i10d426d5": {"j5CeRZDvl": {"asd": "123"}}},
            ),
            format="json",
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_bad_radio(self):
        response = self.client.post(
            URL,
            createSignupRequest("", self.signupFormRadio.id, {"RHJhSoaLD": []}),
            format="json",
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_bad_type_radio(self):
        response = self.client.post(
            URL,
            createSignupRequest(
                "", self.signupFormRadio.id, {"RHJhSoaLD": {"asd": "123"}}
            ),
            format="json",
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        self.assertEqual(Signup.objects.count(), 2)
