import base64

from django.contrib.auth import authenticate
from django.core.files.base import ContentFile
from drf_extra_fields.fields import Base64ImageField
from rest_framework import serializers

from store.exceptions import CRMException, InvalidCredentialsException
from store.models import User, Checklist, GlobalSettings, Category, PaymentMethod, Promocode, Image


class LoginSerializer(serializers.Serializer):
    login = serializers.CharField(write_only=True, required=False)
    password = serializers.CharField(trim_whitespace=False, write_only=True, required=False)

    def validate(self, attrs):
        email = attrs.get('login')
        password = attrs.get('password')

        if not email or not password:
            raise CRMException('login and password is required')

        user = authenticate(request=self.context.get('request'),
                            email=email,
                            password=password)

        # The authenticate call simply returns None for is_active=False
        # users. (Assuming the default ModelBackend authentication
        # backend.)
        if not user:
            raise InvalidCredentialsException()

        attrs['user'] = user
        return attrs


class UserSerializer(serializers.ModelSerializer):
    login = serializers.CharField(source='email', required=False)
    job = serializers.CharField(source='job_title', required=False)
    name = serializers.CharField(source='first_name', required=False)
    lastname = serializers.CharField(source='middle_name', required=False)
    surname = serializers.CharField(source='last_name', required=False)

    class Meta:
        model = User
        fields = ('id', 'login', 'job', 'name', 'lastname', 'surname',)


class ImageSerializer(serializers.ModelSerializer):
    image = Base64ImageField()

    class Meta:
        model = Image
        fields = ('image',)


class ChecklistImageListSerializer(serializers.ListSerializer):
    child = ImageSerializer()

    def to_representation(self, data):
        images = super().to_representation(data)
        return [image['image'] for image in images]


class ChecklistSerializer(serializers.ModelSerializer):
    id = serializers.CharField(read_only=True)
    managerid = serializers.CharField(source='manager.id', read_only=True)
    link = serializers.URLField(source='product_link', required=False)
    category = serializers.SlugRelatedField(slug_field='slug', queryset=Category.objects.all())

    # image = Base64ImageField(source='images', many=True, queryset=Image.objects.all())
    previewimage = serializers.ImageField(source='preview_image_url', read_only=True)

    promo = serializers.SlugRelatedField(source='promocode', slug_field='name',
                                         queryset=Promocode.objects.active(), required=False)

    currency = serializers.SerializerMethodField('get_yuan_rate')
    curencycurency2 = serializers.DecimalField(source='price_yuan', max_digits=10, decimal_places=2)
    currency3 = serializers.DecimalField(source='price_rub', read_only=True, max_digits=10, decimal_places=2)
    chinadelivery = serializers.SerializerMethodField('get_delivery_price_CN', read_only=True)
    chinadelivery2 = serializers.DecimalField(source='delivery_price_CN_RU', read_only=True, max_digits=10,
                                              decimal_places=2)
    fullprice = serializers.DecimalField(source='full_price', read_only=True, max_digits=10, decimal_places=2)
    realprice = serializers.DecimalField(source='real_price', required=False, allow_null=True, max_digits=10,
                                         decimal_places=2)
    comission = serializers.SerializerMethodField('get_comission', read_only=True)

    buyername = serializers.CharField(source='buyer_name', required=False, allow_null=True)
    buyerphone = serializers.CharField(source='buyer_phone', required=False, allow_null=True)
    tg = serializers.CharField(source='buyer_telegram', required=False, allow_null=True)

    receivername = serializers.CharField(source='receiver_name', required=False, allow_null=True)
    reveiverphone = serializers.CharField(source='receiver_phone', required=False, allow_null=True)

    split = serializers.BooleanField(source='is_split_payment', required=False)
    paymenttype = serializers.SlugRelatedField(source='payment_method', slug_field='slug',
                                               queryset=PaymentMethod.objects.all(),
                                               required=False, allow_null=True)
    paymentproovement = serializers.ImageField(source='payment_proof', required=False, allow_null=True)
    checkphoto = serializers.ImageField(source='receipt', required=False, allow_null=True)
    trackid = serializers.CharField(source='poizon_tracking', required=False, allow_null=True)
    cdek_tracking = serializers.CharField(required=False, allow_null=True)
    delivery = serializers.CharField(source='get_delivery_display', required=False, allow_null=True)

    startDate = serializers.DateTimeField(source='created_at', read_only=True)
    currentDate = serializers.DateTimeField(source='status_updated_at', read_only=True)

    @staticmethod
    def get_yuan_rate(obj: Checklist):
        return GlobalSettings.load().yuan_rate

    @staticmethod
    def get_image(obj: Checklist):
        return obj.images.all()

    @staticmethod
    def get_delivery_price_CN(obj: Checklist):
        return GlobalSettings.load().delivery_price_CN

    @staticmethod
    def get_comission(obj: Checklist):
        return GlobalSettings.load().commission_rub

    class Meta:
        model = Checklist
        fields = ('id', 'status', 'managerid', 'link',
                  'category', 'subcategory',
                  'brand', 'model', 'size',
                  # 'image',
                  'previewimage',
                  'currency', 'curencycurency2', 'currency3', 'chinadelivery', 'chinadelivery2', 'comission',
                  'promo',
                  'comment',
                  'fullprice', 'realprice',
                  'buyername', 'buyerphone', 'tg',
                  'receivername', 'reveiverphone',
                  'split', 'paymenttype', 'paymentproovement', 'checkphoto',
                  'trackid', 'cdek_tracking', 'cdek_barcode_pdf', 'delivery',
                  'startDate', 'currentDate',
                  )


class GlobalSettingsYuanRateSerializer(serializers.ModelSerializer):
    currency = serializers.DecimalField(source='yuan_rate', max_digits=10, decimal_places=2)

    class Meta:
        model = GlobalSettings
        fields = ('currency',)


class GlobalSettingsPickupSerializer(serializers.ModelSerializer):
    pickup = serializers.CharField(source='pickup_address')

    class Meta:
        model = GlobalSettings
        fields = ('pickup',)


class GlobalSettingsPriceSerializer(serializers.ModelSerializer):
    comission = serializers.DecimalField(source='commission_rub', max_digits=10, decimal_places=2)
    chinadelivery = serializers.DecimalField(source='delivery_price_CN', max_digits=10, decimal_places=2)

    class Meta:
        model = GlobalSettings
        fields = ('comission', 'chinadelivery')


class CategorySerializer(serializers.ModelSerializer):
    category = serializers.CharField(source='slug')
    chinarush = serializers.DecimalField(source='delivery_price_CN_RU', max_digits=10, decimal_places=2)

    class Meta:
        model = Category
        fields = ('category', 'chinarush')


class PaymentMethodSerializer(serializers.ModelSerializer):
    type = serializers.CharField(source='slug')

    class Meta:
        model = PaymentMethod
        fields = ('type', 'name', 'requisites', 'cardnumber')


class PromocodeSerializer(serializers.ModelSerializer):
    freedelivery = serializers.BooleanField(source='free_delivery')
    nocomission = serializers.BooleanField(source='no_comission')

    class Meta:
        model = Promocode
        fields = ('id', 'name', 'discount', 'freedelivery', 'nocomission', 'is_active')
