from rest_framework import serializers
from rest_framework.serializers import CharField
from django.core.validators import *


err_msg = {
    'invalid': '此字段类型错误，无效的参数',
    'invalid_choice': '参数超出可选范围',
    'phone': "手机号不合法",
    'blank': '此字段不能为空字符串',
    'max_length': '此字段超出最大长度: {max_length}',
    'min_length': '此字段不足最少长度: {min_length}',
    'max_value': '确保此值小于或等于{max_value}',
    'min_value': '确保此值大于或等于{min_value}',
    'max_string_length': '此字段字符串值太大',
    'required': '此字段必填',
    'null': '此字段不能为空。',
    'not_a_dict': '此字段需要是字典类型，但获得类型“{input_type}”',
    'empty': '该字典可能不是空的',
    'date': '此字段需要datetime类型得到了date类型',
    'make_aware': '此字段时区“{timezone}”的日期时间无效',
    'overflow': '此字段日期时间值超出范围',
    'max_digits': '确保此字段总共不超过{max_digits}位',
    'max_decimal_places': '确保此字段小数位数不超过{max_decimal_places}',
    'max_whole_digits': '确保此字段小数点前的位数不超过{max_整位数}。',
    'not_a_list': '此字段需要是列表类型，但获得类型“{input_type}”',
}


def _lazy_re_compile(regex, flags=0):
    """Lazily compile a regex with flags."""
    def _compile():
        # Compile the regex if it was not passed pre-compiled.
        if isinstance(regex, str):
            return re.compile(regex, flags)
        else:
            assert not flags, "flags must be empty if regex is passed pre-compiled"
            return regex
    return SimpleLazyObject(_compile)


@deconstructible
class PhoneValidator:
    message = ('手机号不合法.')
    code = 'phone'
    phone = _lazy_re_compile(
        r"(^1[0-9]{10}$)",
        re.IGNORECASE)

    def __init__(self, message=None, code=None, whitelist=None):
        if message is not None:
            self.message = message
        if code is not None:
            self.code = code
        if whitelist is not None:
            self.domain_whitelist = whitelist

    def __call__(self, value):
        if not self.phone.match(value):
            raise ValidationError(self.message, code=self.code)

    def __eq__(self, other):
        return (
                isinstance(other, PhoneValidator) and
                (self.domain_whitelist == other.domain_whitelist) and
                (self.message == other.message) and
                (self.code == other.code)
        )


class PhoneField(CharField):
    default_error_messages = {
        'phone': ('手机号不合法')
    }

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        validator = PhoneValidator(message=self.error_messages['phone'])
        self.validators.append(validator)


class BaseDataSerializer(serializers.Serializer):
    pass


class BaseSerializer(serializers.Serializer):
    msg = serializers.CharField(help_text="英文描述")
    msg_show = serializers.CharField(help_text="中文描述")
    code = serializers.IntegerField(help_text="状态码")


def serializer_assembly(instance, many=False):
    if many:
        BaseDataSerializer._declared_fields['bean'] = serializers.DictField()
        BaseDataSerializer._declared_fields['list'] = instance(many=many)
        BaseSerializer._declared_fields['page'] = serializers.IntegerField(
            required=False, help_text="页码")
        BaseSerializer._declared_fields[
            'page_size'] = serializers.IntegerField(required=False,
                                                    help_text="每页数量")
        BaseSerializer._declared_fields['count'] = serializers.IntegerField(
            required=False, help_text="共计")
    else:
        BaseDataSerializer._declared_fields['bean'] = instance()
        BaseDataSerializer._declared_fields['list'] = serializers.ListField()
    BaseSerializer._declared_fields['data'] = BaseDataSerializer()
    return BaseSerializer
