import structlog
from graphene import ClientIDMutation, Field, Int, List, String
from graphene.types.generic import GenericScalar
from graphene_django.types import ErrorType

from vbv_lernwelt.course.models import CourseSession
from vbv_lernwelt.feedback.graphql.types import FeedbackResponse as FeedbackResponseType
from vbv_lernwelt.feedback.models import FeedbackResponse
from vbv_lernwelt.feedback.serializers import CourseFeedbackSerializer
from wagtail.models import Page

logger = structlog.get_logger(__name__)


# https://medium.com/open-graphql/jsonfield-models-in-graphene-django-308ae43d14ee
class SendFeedback(ClientIDMutation):
    feedback_response = Field(FeedbackResponseType)
    errors = List(
        ErrorType, description="May contain more than one error for same field."
    )

    class Input:
        page = String(required=True)
        course_session = Int(required=True)
        data = GenericScalar()

    @classmethod
    def mutate_and_get_payload(cls, _, info, **input):
        page_key = input["page"]
        course_session_id = input["course_session"]
        logger.info("creating feedback")

        learning_content = Page.objects.get(
            translation_key=page_key, locale__language_code="de-CH"
        )
        circle = learning_content.get_parent().specific
        course_session = CourseSession.objects.get(id=course_session_id)
        data = input.get("data", {})

        serializer = CourseFeedbackSerializer(data=data)

        if not serializer.is_valid():
            logger.error(serializer.errors)
            return SendFeedback(errors=serializer.errors)

        feedback_response = FeedbackResponse.objects.create(
            circle=circle,
            course_session=course_session,
            data=serializer.validated_data,
        )
        logger.info(feedback_response)

        return SendFeedback(feedback_response=feedback_response)


class FeedbackMutation(object):
    send_feedback = SendFeedback.Field()
