from django.contrib.auth import get_user_model
from rest_framework import serializers
from uncloud_auth.serializers import UserSerializer
from django.utils.translation import gettext_lazy as _
from stripe.error import CardError

from .models import *
import uncloud_pay.stripe as uncloud_stripe
from uncloud import AMOUNT_DECIMALS, AMOUNT_MAX_DIGITS

###
# 2020-12 Checked code

class StripeCreditCardSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = StripeCreditCard
        exclude = [ "card_id", "owner" ]
        read_only_fields = [ "last4", "brand", "expiry_date" ]

class PaymentSerializer(serializers.ModelSerializer):
    owner = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Payment
        fields = '__all__'
        read_only_fields = [ "external_reference", "source", "timestamp" ]

    def validate(self, data):
        data["source"] = "stripe"
        return data
        
    def create(self, validated_data):
        try:
            if validated_data['type'] == 'deposit':
                return Payment.deposit(validated_data['owner'], validated_data['amount'], validated_data['source'], currency=validated_data['currency'], notes=validated_data['notes'])
            else:
                return Payment.objects.create(**validated_data)
        except CardError as err:
            raise serializers.ValidationError(err.user_message)

class BalanceSerializer(serializers.Serializer):
    balance = serializers.DecimalField(max_digits=AMOUNT_MAX_DIGITS, decimal_places=AMOUNT_DECIMALS)

class BillingAddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = BillingAddress
        exclude = [ "owner" ]


class VATRateSerializer(serializers.ModelSerializer):

    class Meta:
        model = VATRate
        fields = '__all__'


################################################################################
# Unchecked code


###
# Orders & Products.

class OrderSerializer(serializers.ModelSerializer):
    owner = serializers.PrimaryKeyRelatedField(queryset=get_user_model().objects.all())

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        admin = kwargs.pop('admin', None)

        # Instantiate the superclass normally
        super(OrderSerializer, self).__init__(*args, **kwargs)

        # Only allows owner in admin mode.
        if not admin:
            self.fields.pop('owner')

    def create(self, validated_data):
        billing_address = BillingAddress.get_preferred_address_for(validated_data["owner"])
        instance = Order(billing_address=billing_address, **validated_data)
        instance.save()

        return instance

    def validate_owner(self, value):
        if BillingAddress.get_preferred_address_for(value) == None:
            raise serializers.ValidationError("Owner does not have a valid billing address.")

        return value

    class Meta:
        model = Order
        read_only_fields = ['replaced_by', 'depends_on']
        fields = ['owner', 'description', 'creation_date', 'starting_date', 'ending_date',
                'recurring_period', 'recurring_price', 'one_time_price', 
                'config', 'pricing_plan', 'should_be_billed'] + read_only_fields


###
# Bills

# TODO: remove magic numbers for decimal fields
class BillRecordSerializer(serializers.Serializer):
    order = serializers.HyperlinkedRelatedField(
            view_name='order-detail',
            read_only=True)
    description = serializers.CharField()
    one_time_price = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)
    recurring_price = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)
#    recurring_period = serializers.ChoiceField()
    recurring_count = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)
    vat_rate = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)
    vat_amount = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)
    amount = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)
    total = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)

class BillSerializer(serializers.ModelSerializer):
    billing_address = BillingAddressSerializer(read_only=True)
    records = BillRecordSerializer(many=True, read_only=True)

    class Meta:
        model = Bill
        fields = ['owner', 'sum', 'vat_rate',
                'due_date', 'creation_date', 'starting_date', 'ending_date',
                'records', 'status', 'billing_address']

# We do not want users to mutate the country / VAT number of an address, as it
# will change VAT on existing bills.
class UpdateBillingAddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = BillingAddress
        fields = ['street', 'city', 'postal_code']
