from typing import Union

import structlog

from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.models import CourseCompletionStatus, CourseSession
from vbv_lernwelt.course.services import mark_course_completion
from vbv_lernwelt.feedback.models import FeedbackResponse
from vbv_lernwelt.learnpath.models import (
    LearningContentFeedbackUK,
    LearningContentFeedbackVV,
)

logger = structlog.get_logger(__name__)


def update_feedback_response(
    feedback_user: User,
    course_session: CourseSession,
    learning_content_feedback_page: Union[
        LearningContentFeedbackUK, LearningContentFeedbackVV
    ],
    submitted: bool,
    validated_data: dict,
):
    circle = learning_content_feedback_page.get_circle()

    feedback_response, _ = FeedbackResponse.objects.get_or_create(
        feedback_user_id=feedback_user.id,
        circle_id=circle.id,
        course_session=course_session,
    )

    original_data = feedback_response.data
    updated_data = validated_data
    initial_data = initial_data_for_feedback_page(learning_content_feedback_page)

    merged_data = initial_data | {
        key: updated_data[key]
        if updated_data.get(key, "") != ""
        else original_data.get(key)
        for key in initial_data.keys()
    }

    feedback_response.data = merged_data

    # save the response before completion mark,
    # because who knows what could happen in between...
    if submitted:
        feedback_response.submitted = submitted
    feedback_response.save()

    if submitted:
        mark_course_completion(
            user=feedback_user,
            page=learning_content_feedback_page,
            course_session=course_session,
            completion_status=CourseCompletionStatus.SUCCESS.value,
        )

    logger.info(
        "feedback successfully created",
        label="feedback",
        feedback_user_id=feedback_user.id,
        circle_title=circle.title,
        course_session_id=course_session.id,
    )

    return feedback_response


def initial_data_for_feedback_page(
    learning_content_feedback_page: Union[
        LearningContentFeedbackUK, LearningContentFeedbackVV
    ]
):
    if hasattr(learning_content_feedback_page, "learningcontentfeedbackuk"):
        return {
            "satisfaction": None,
            "goal_attainment": None,
            "proficiency": None,
            "preparation_task_clarity": None,
            "instructor_competence": None,
            "instructor_respect": None,
            "instructor_open_feedback": "",
            "would_recommend": None,
            "course_negative_feedback": "",
            "course_positive_feedback": "",
            "feedback_type": "uk",
        }
    if hasattr(learning_content_feedback_page, "learningcontentfeedbackvv"):
        return {
            "satisfaction": None,
            "goal_attainment": None,
            "proficiency": None,
            "preparation_task_clarity": None,
            "would_recommend": None,
            "course_negative_feedback": "",
            "course_positive_feedback": "",
            "feedback_type": "vv",
        }
    return {}
