from django.contrib.auth.decorators import permission_required
from django.core.exceptions import ValidationError
from django.db import transaction
from django.shortcuts import get_object_or_404

from common.decorators import ajax
from unifier.models import UnifiedFrame, UnifiedFrame2SlowalFrameMapping, UnifiedFrameArgumentSlowalFrameMapping
from users.models import Assignment

from . import choices
from .models import Frame


@ajax(login_required=True, method='post')
@transaction.atomic
def frame_mark_as_invalid(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.NEW).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.INVALID
    frame.save()
    return {}

@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_confirm_invalid(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.INVALID).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.BAD
    frame.save()
    removeSlovalFrameMappingsAndAssigments(frame_pk)
    return {}


@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_reject_invalid(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.INVALID).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.NEW
    frame.save()
    removeSlovalFrameMappingsAndAssigments(frame_pk)
    return {}

@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_mark_as_bad(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.NEW).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.BAD
    frame.save()
    removeSlovalFrameMappingsAndAssigments(frame_pk)
    return {}

def removeSlovalFrameMappingsAndAssigments(frame_pk):
    #odpianie z ramy zunifikowanej
    unifiedFrame2SlowalFrameMappings = UnifiedFrame2SlowalFrameMapping.objects.filter(slowal_frame_id=frame_pk)
    for unifiedFrame2SlowalFrameMapping in unifiedFrame2SlowalFrameMappings:
        unifiedFrameArgumentSlowalFrameMappings = UnifiedFrameArgumentSlowalFrameMapping.objects.filter(unified_frame_mapping=unifiedFrame2SlowalFrameMapping)
        for unifiedFrameArgumentSlowalFrameMapping in unifiedFrameArgumentSlowalFrameMappings:
            unifiedFrameArgumentSlowalFrameMapping.delete()
        unifiedFrame2SlowalFrameMapping.delete()
    Assignment.delete(subject_id=frame_pk)

@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_reject_as_not_matching_unified_frame(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.NOT_MATCHING_UNIFIED_FRAME).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.PROCESSING
    frame.save()
    return {}

@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_confirm_as_not_matching_unified_frame(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.NOT_MATCHING_UNIFIED_FRAME).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.NEW
    frame.save()
    removeSlovalFrameMappingsAndAssigments(frame_pk)
    return {}