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 .models import *

###
# Payments and Payment Methods.

class PaymentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Payment
        fields = '__all__'

class PaymentMethodSerializer(serializers.ModelSerializer):
    stripe_card_last4 = serializers.IntegerField()

    class Meta:
        model = PaymentMethod
        fields = ['uuid', 'source', 'description', 'primary', 'stripe_card_last4', 'active']

class UpdatePaymentMethodSerializer(serializers.ModelSerializer):
    class Meta:
        model = PaymentMethod
        fields = ['description', 'primary']

class ChargePaymentMethodSerializer(serializers.Serializer):
    amount = serializers.DecimalField(max_digits=10, decimal_places=2)

class CreatePaymentMethodSerializer(serializers.ModelSerializer):
    please_visit = serializers.CharField(read_only=True)
    class Meta:
        model = PaymentMethod
        fields = ['source', 'description', 'primary', 'please_visit']

###
# Orders & Products.

class OrderRecordSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderRecord
        fields  = ['one_time_price', 'recurring_price', 'description']


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 = ['uuid', 'owner', 'description', 'creation_date', 'starting_date', 'ending_date',
                'bill', 'recurring_period', 'recurring_price', 'one_time_price'] + 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(choices=RecurringPeriod.choices)
    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 BillingAddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = BillingAddress
        fields = ['uuid', 'organization', 'name', 'street', 'city', 'postal_code', 'country', 'vat_number']

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

    class Meta:
        model = Bill
        fields = ['uuid', 'reference', 'owner', 'amount', 'vat_amount', 'total',
                'due_date', 'creation_date', 'starting_date', 'ending_date',
                'records', 'final', '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 = ['uuid', 'street', 'city', 'postal_code']