from rest_framework import serializers

from question.models import QUESTION_FORMAT_SERIALIZER_CHOICES
from utils.validators import dic_validetor


def user_inputs_validator(data):
    # check if user_inputs is a dictionary
    if type(data) is not list:
        raise serializers.ValidationError({'user_inputs': 'user_inputs should be a list'})

    if len(data) == 0:
        raise serializers.ValidationError({'user_inputs': 'At least one user_input is required'})

    index = {'key': 'index', 'type': int}

    answer_text = {'key': 'answer_text', 'type': str}

    answer_text_format = {'key': 'answer_text_format', 'type': str,
                          'validator': lambda format: format in QUESTION_FORMAT_SERIALIZER_CHOICES,
                          'validator_error_message': f'answer_text_format should be one of {", ".join(QUESTION_FORMAT_SERIALIZER_CHOICES)}'}

    selected_choices = {'key': 'selected_choices', 'type': list}
    # check for required and optional fields
    required_items = [index]
    optional_items = [answer_text, answer_text_format, selected_choices]

    for user_input in data:
        # check_for_required_and_optional_fields(user_input, required_items, optional_items, 'user_inputs', 'rules', parent_is_array=True)
        dic_validetor(data=user_input, required_items=required_items, optional_items=optional_items, error_key='user_inputs',
                      many=True, container_name='user_inputs',
                      raise_error_for_unexpected_key=True)  # validations on selected_choices, ... are don in views because we need more data for validating them  # if "answer_text_format" in user_input :  #     answer_text_format_validator(input = user_input['answer_text_format'])

    # check for duplicate question index
    user_input_question_priorities = []
    for user_input in data:
        if user_input['index'] in user_input_question_priorities:
            raise serializers.ValidationError({'user_inputs': f'Duplicate index="{user_input["index"]}"'})
        user_input_question_priorities.append(user_input['index'])

        if 'selected_choices' in user_input:
            for answer_index in user_input['selected_choices']:
                if type(answer_index) is not str:
                    raise serializers.ValidationError({'user_inputs': f'selected_choices must be a list of strings'})


def token_quiz_id_quiz_sheet_id_entrance_token_validator(data):
    if 'entrance_token' in data and 'token' in data:
        raise serializers.ValidationError({'entrance_token': 'Only one of these fields should be given: token, entrance_token'})

    if 'quiz_id' in data and 'quiz_sheet_id' in data:
        raise serializers.ValidationError({'quiz_sheet_id': 'Only one of these fields should be given: quiz_id, quiz_sheet_id'})

    if 'quiz_id' in data and 'entrance_token' in data:
        raise serializers.ValidationError({'quiz_id': 'Only one of these fields should be given: quiz_id, entrance_token'})

    if 'quiz_sheet_id' in data and 'entrance_token' in data:
        raise serializers.ValidationError(
            {'quiz_sheet_id': 'Only one of these fields should be given: quiz_sheet_id, entrance_token'})

    if 'quiz_id' not in data and 'quiz_sheet_id' not in data and 'entrance_token' not in data:
        raise serializers.ValidationError(
            {'quiz_id': 'One of these fields should be given: quiz_id, quiz_sheet_id, entrance_token'})
