import re

from rest_framework import serializers

from authenticate import utils


def email_validator(email):
    """
    This function checks if the incoming email is valid or not!
    """
    if not re.match('^[\\w!#$%&’*+/=?`{|}~^-]+(?:\\.[\\w!#$%&’*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$', email):
        raise serializers.ValidationError('Enter a valid email address')
    return email


def phone_validator(phone):
    """
    This function checks if the incoming phone is valid or not!
    """
    if not phone.isdigit():
        raise serializers.ValidationError('phone characters should be digits')
    phone = utils.replace_phone_persian_digits_with_english_digits(phone)

    # TODO dead code?
    if not phone.isascii():
        raise serializers.ValidationError('Enter a valid phone')

    phone = utils.iran_phone_number_modifier(phone)
    if len(phone) != 11:
        raise serializers.ValidationError('Enter a valid phone')
    return phone


def password_validator(password):
    """
    This function checks if the incoming password is strong or not!
    it should be between 8 to 50 characters.
    """
    if not 7 < len(password) < 21:
        raise serializers.ValidationError(
            'Password length should be between 8 to 20 characters')
    if not re.match('^(?=.*[A-Z])(?=.*\d)', password):
        raise serializers.ValidationError(
            'Password should contain at least an uppercase letter and a digit')
    return password


def code_validator(code):
    """
    This function checks if the incoming code is valid or not!
    it should has exactly 8 integer characters.
    """
    if not re.match('^[0-9]{6}$', code):
        raise serializers.ValidationError('Enter a valid verification code')
    return code


def info_validator(info):
    """
    This function gets info as its argument and checks the format of it
    """
    if type(info) is not dict or 'bio' not in info or len(info) > 1:
        raise serializers.ValidationError('Info format is incorrect')
    if len(info['bio']) > 3000:
        raise serializers.ValidationError(
            'bio can not has more than 3000 characters')
    return info


def make_email_or_phone_required_validator(data):
    email = data.get('email', None)
    phone = data.get('phone', None)
    if (not email and not phone) or (email and phone):
        raise serializers.ValidationError('You should send phone or email')


def make_email_or_phone_or_username_required_validator(data):
    email = data.get('email', None)
    phone = data.get('phone', None)
    username = data.get('username', None)
    count = (email is not None) + (phone is not None) + (username is not None)
    if count != 1:
        raise serializers.ValidationError('You should send phone or email or username')
